常见错误点:
- 虑节点为 null 导致空指针异常;
- 现节点位置定位出错,比如往前多走了一步,或者少走了一步;
基本思想:
- 双指针(快慢指针):判断有环,倒数多少个节点,第一个公共节点
题目:
-
// 递归思想,从尾到头进行push_back // 时间链表长度O(n), 空间递归深度O(n) class Solution { public: vector<int> ans; void dfs(ListNode* head) { if(!head) return; dfs(head->next); ans.push_back(head->val); } vector<int> reversePrint(ListNode* head) { dfs(head); return ans; } }; // 倒叙填充,时间链表长度O(n),没有额外空间开辟O(1) class Solution { public: vector<int> reversePrint(ListNode* head) { if(!head) return vector<int>{}; ListNode *cur = head; int k =0; while(cur) { ++k; cur=cur->next; } vector<int> ans(k); cur = head; for(int i =k-1;i>=0;--i) { ans[i] = cur->val; cur = cur->next; } return ans; } };
-
// 递归思想:时间链表长度O(n),递归空间O(n) class Solution { public: ListNode* reverseList(ListNode* head) { if(head ==NULL || head->next ==NULL) return head; ListNode *temp = reverseList(head->next); head->next->next = head; head->next = NULL; return temp; } }; // 原地置换,时间O(n),空间O(1) class Solution { public: ListNode* reverseList(ListNode* head) { if(!head || !head->next) return head; ListNode *pre = NULL,*cur = head; while(cur) { ListNode *tmp = cur->next; cur->next = pre; pre = cur; cur = tmp; } return pre; } };
-
// 拼接和拆分,时间O(n),空间O(1) class Solution { public: Node* copyRandomList(Node* head) { if(!head) return head; Node* cur = head; while(cur) { Node* next = cur->next; cur->next = new Node(cur->val); cur->next->next = next; cur = next; } cur = head; while(cur) { if(cur->random) cur->next->random = cur->random->next; cur = cur->next->next; } cur = head; Node* newHead = head->next; Node* newCur = newHead; while(cur) { cur->next = cur->next->next; cur = cur->next; newCur->next = cur?cur->next:NULL; newCur = newCur->next; } return newHead; } }; // 哈希表,时间O(n),空间O(n) class Solution { public: Node* copyRandomList(Node* head) { if(!head) return head; unordered_map<Node*,Node*> m; Node* cur = head; while(cur) { m[cur] = new Node(cur->val); cur = cur->next; } cur = head; while(cur) { m[cur]->next = m[cur->next]; m[cur]->random = m[cur->random]; cur = cur->next; } return m[head]; } };
-
/** * struct ListNode { * int val; * struct ListNode *next; * ListNode(int x) : val(x), next(nullptr) {} * }; */ class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { // write code here if(!head) return nullptr; ListNode* newHead = new ListNode(-1); newHead->next = head; ListNode* pre = newHead,* cur = head,*deleteNode = head; for(int i=0;i<n;++i) { if(cur) cur = cur->next; else return nullptr; } while(cur) { cur = cur->next; pre = pre->next; deleteNode = deleteNode->next; } pre->next = deleteNode->next; return newHead->next; } };
-
/** * struct ListNode { * int val; * struct ListNode *next; * ListNode(int x) : val(x), next(nullptr) {} * }; */ #include <bits/types/struct_tm.h> #include <list> class Solution { public: ListNode* reverseList(ListNode* head) { if(!head) return head; ListNode *pre =nullptr; ListNode *cur = head; while (cur) { ListNode *tmp = cur->next; cur->next = pre; pre = cur; cur = tmp; } return pre; } ListNode* addInList(ListNode* head1, ListNode* head2) { ListNode* newHead1 = reverseList(head1); ListNode* newHead2 = reverseList(head2); ListNode* cur1 = newHead1,*cur2 = newHead2; ListNode* ansHead = new ListNode(-1); ListNode* ans = ansHead; int flag = 0; while(cur1 || cur2) { int val1 = cur1?cur1->val:0; int val2 = cur2?cur2->val:0; int sum = val1 + val2 + flag; if(sum>=10) { flag = 1; sum = sum%10; } else flag = 0; ans->next = new ListNode(sum); ans = ans->next; if(cur1)cur1= cur1->next; if(cur2)cur2= cur2->next; } if(flag) ans->next = new ListNode(1); ans = reverseList(ansHead->next); return ans; } };
-
-
双指针解法
class Solution { public: void reverse1(ListNode*head) { ListNode* pre = nullptr,* cur = head; while(cur) { ListNode* tmp = cur->next; cur->next = pre; pre = cur; cur = tmp; } } ListNode* reverseBetween(ListNode* head, int m, int n) { // write code here if(m==n||!head) return head; ListNode* dummyNode = new ListNode(-1); dummyNode->next = head; ListNode* pre = dummyNode; for(int i=0;i<m-1;i++) { pre = pre->next; } ListNode* rightNode = head; for(int i=1;i<n;++i) { rightNode=rightNode->next; } ListNode* leftNode = pre->next; ListNode* cur = rightNode->next; pre->next = nullptr; rightNode->next = nullptr; reverse1(leftNode); pre->next = rightNode; leftNode->next = cur; return dummyNode->next; } };
-
单指针解法
#include <bits/types/struct_tm.h> class Solution { public: ListNode* reverseBetween(ListNode* head, int m, int n) { // write code here if(m==n||!head) return head; ListNode* dummyNode = new ListNode(-1); dummyNode->next = head; ListNode* pre = dummyNode; for(int i=0;i<m-1;i++) { pre = pre->next; } ListNode* cur = pre->next; for(int i=0;i<n-m;i++) { ListNode* tmp = cur->next; cur->next = tmp->next; tmp->next = pre->next; pre->next = tmp; } return dummyNode->next; } };
-