Leetcode 203. Remove Linked List Elements
删除节点:p->next = p->next->next
本题还需要考虑到头节点值为val的情况,所以设置一个虚拟头节点dum,让原来的头节点变为一般情况。最后结果只要返回dum->next就可以了。
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dum = new ListNode(0);
dum->next = head;
auto p = dum;
while(p->next != NULL){
if(p->next->val == val){
p->next = p->next->next;
}else{
p = p->next;
}
}
return dum->next;
}
};
Leetcode 707. Design Linked List
这道题涵盖了链表的常见操作,如果一时想不明白可以找在纸上画一画便于理解。
class MyLinkedList {
public:
struct Node {
int val;
Node* next;
Node(int _val): val(_val), next(NULL) {};
}*head;
MyLinkedList() {
head = NULL;
}
int get(int index) {
if(index < 0) return -1;
auto p = head;
for(int i = 0; i < index && p; i ++) p = p->next;
if(!p) return -1;
return p->val;
}
void addAtHead(int val) {
auto cur = new Node(val);
cur->next = head;
head = cur;
}
void addAtTail(int val) {
if(!head) head = new Node(val);
else{
auto p = head;
while(p->next) p = p->next;
p->next = new Node(val);
}
}
void addAtIndex(int index, int val) {
if(index <= 0) addAtHead(val);
else{
int len = 0;
for(auto p = head; p; p = p->next) len ++;
if(index == len) addAtTail(val);
else if(index < len){
auto p = head;
for(int i = 0; i < index - 1; i ++) p = p->next;
auto cur = new Node(val);
cur->next = p->next;
p->next = cur;
}
}
}
void deleteAtIndex(int index) {
int len = 0;
for(auto p = head; p; p = p->next) len ++;
if(index >= 0 && index < len){
if(!index) head = head->next;
else{
auto p = head;
for(int i = 0; i < index - 1; i ++) p = p->next;
p->next = p->next->next;
}
}
}
};
Leetcode 206. Reverse Linked List
翻转即将所有节点的next指针指向前驱节点。 由于是单链表,我们在迭代时不能直接找到前驱节点,所以我们需要一个额外的指针保存前驱节点。同时在改变当前节点的next指针前,不要忘记保存它的后继节点。
空间复杂度分析:遍历时只有3个额外变量,所以额外的空间复杂度是O(1)。
时间复杂度分析:只遍历一次链表,时间复杂度是O(n)。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head || !head->next) return head;
auto p = head, q = p->next;
while(q){
auto o = q->next;
q->next = p;
p = q, q = o;
}
head->next = NULL;
return p;
}
};