203
思路
设置一个虚拟头结点,这样所有节点就都可以按照统一的方式进行移除。
如果下一个节点的值等于 val,让节点 next 指针直接指向下下一个节点。
不要忘记清理节点内存。
时间复杂度: O(n)
空间复杂度: O(1)
代码
cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dumphead = new ListNode(0, head);
ListNode* pre = dumphead;
while(pre->next != nullptr){
if(pre->next->val == val){
ListNode* tmp = pre->next;
pre->next = pre->next->next;
delete tmp;
}
else{
pre = pre->next;
}
}
head = dumphead->next;
delete dumphead;
return head;
}
};
707
思路
addAtHead(val) 和 addAtTail(val) 可以借助 addAtIndex(index, val) 来实现
根据题意,优先判断 index 的有效性
使用虚拟头结点和变量size记录节点数
时间复杂度:get O(index),addAtHead O(1),addAtTail O(n),addAtIndex O(index),deleteAtIndex O(index)
空间复杂度:单函数 O(1),总体 O(n)
代码
cpp
class MyLinkedList {
public:
MyLinkedList() {
dummyhead = new ListNode(0);
size = 0;
}
int get(int index) {
ListNode* getnode = dummyhead;
if(index<0 || index>=size){
return -1;
}
for(int i=0; i<=index; i++){
getnode = getnode->next;
}
return getnode->val;
}
void addAtHead(int val) {
return addAtIndex(0, val);
}
void addAtTail(int val) {
return addAtIndex(size, val);
}
void addAtIndex(int index, int val) {
ListNode* node = dummyhead;
if(index>size){
return;
}
index = max(0,index);
for(int i=0; i<index; i++){
node = node->next;
}
ListNode* newnode = new ListNode(val);
newnode->next = node->next;
node->next = newnode;
size++;
}
void deleteAtIndex(int index) {
ListNode* node = dummyhead;
if(index<0 || index>=size){
return;
}
for(int i=0; i<index; i++){
node = node->next;
}
ListNode* tmp = node->next;
node->next = node->next->next;
delete tmp;
size--;
}
private:
ListNode* dummyhead;
int size;
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/
206
思路
在遍历链表时,将当前节点的 next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。
时间复杂度: O(n)
空间复杂度: O(1)
代码
cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *pre = nullptr, *cur = head, *temp;
while(cur != nullptr){
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};