【LeetCode】鏈表 linked list(共34題)

【2】Add Two Numbers (2018年11月30日,第一次review,ko)node

兩個鏈表,表明兩個整數的逆序,返回一個鏈表,表明兩個整數相加和的逆序。算法

Example:
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.
 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
12         if (!l1 || !l2) {
13             return l1 == nullptr ? l2 : l1;
14         }
15         ListNode *h1 = l1, *h2 = l2;
16         ListNode *head = 0, *tail = 0;
17         int carry = 0;
18         while (h1 && h2) {
19             int num = h1->val + h2->val + carry;
20             carry = num / 10, num %= 10;
21             ListNode* node = new ListNode(num);
22             if (!head) {
23                 tail = head = node;
24             } else {
25                 tail = tail->next = node;
26             }
27             h1 = h1->next, h2 = h2->next;
28         }
29         while (h1) {
30             int num = h1->val + carry;
31             carry = num / 10, num %= 10;
32             ListNode* node = new ListNode(num);
33             tail = tail->next = node;
34             h1 = h1->next;
35         }
36         while (h2) {
37             int num = h2->val + carry;
38             carry = num / 10, num %= 10;
39             ListNode* node = new ListNode(num);
40             tail = tail->next = node;
41             h2 = h2->next;
42         }
43         if (carry) {
44             ListNode* node = new ListNode(carry);
45             carry = 0;
46             tail = tail->next = node;
47         }
48         return head;
49     }
50 };
View Code

 

【19】Remove Nth Node From End of List (2018年10月30日 算法羣)數組

給了一個鏈表,從尾部刪除第 N 個結點。dom

題解:two pointers,fast 先走 N 步,而後slow,fast 一塊兒走,fast走到最後一個非空結點,slow就走到了要刪除結點的前一個結點。(注意有個特判狀況是若是第N個結點是頭節點,那麼要特殊處理)ide

 1 /**  2  * Definition for singly-linked list.  3  * struct ListNode {  4  * int val;  5  * ListNode *next;  6  * ListNode(int x) : val(x), next(NULL) {}  7  * };  8  */
 9 class Solution { 10 public: 11     ListNode* removeNthFromEnd(ListNode* head, int n) { 12         if (!head) {return head;} 13         ListNode *fast = head, *slow = head; 14         //1. fast goes n steps first
15         for (int k = 0; k < n && fast; ++k) { 16             fast = fast->next; 17  } 18         //2. both slow and fast move simultaneously until fast to the end of the list
19         if (fast) { 20             while (fast->next) { 21                 slow = slow->next; 22                 fast = fast->next; 23  } 24             slow->next = slow->next->next; 25         } else { 26             head = head->next; 27  } 28         return head; 29  } 30 };
View Code 

 

【21】Merge Two Sorted Lists 函數

合併兩個有序鏈表變成一個大鏈表,大鏈表要求有序。(歸併排序)spa

題解:無,直接歸併3d

 1 /**  2  * Definition for singly-linked list.  3  * struct ListNode {  4  * int val;  5  * ListNode *next;  6  * ListNode(int x) : val(x), next(NULL) {}  7  * };  8  */
 9 class Solution { 10 public: 11     ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { 12         if (!l1) {return l2;} 13         if (!l2) {return l1;} 14         ListNode *p1 = l1, *p2 = l2, *head = 0, *tail = 0; 15         while (p1 && p2) { 16             if (p1->val < p2->val) { 17                 if(!head) { 18                     tail = head = p1; 19                 } else { 20                     tail = tail->next = p1; 21  } 22                 p1 = p1->next; 23             } else { 24                 if (!head) { 25                     tail = head = p2; 26                 } else { 27                     tail = tail->next = p2; 28  } 29                 p2 = p2->next; 30  } 31  } 32         //這裏其實不用遍歷了,直接連起來ok
33         if (p1) { 34             tail->next = p1; 35  } 36         if (p2) { 37             tail->next = p2; 38  } 39         return head; 40  } 41 };
View Code

 

【23】Merge k Sorted Lists
指針

給了k個已經排好序的鏈表,要返回一個綜合排序的大鏈表(歸併排序)調試

題解:用 prioprity_queue 的運算符()重載來實現比較函數。具體運算符重載的實現方法見代碼。(奇怪的是爲啥pq的cmp函數要寫 > ,pq裏面纔是從小到大排序?)

這個題目其實應該複習 priority_queue 的比較函數的實現方法。(要搞懂原理。)

 1 /**  2  * Definition for singly-linked list.  3  * struct ListNode {  4  * int val;  5  * ListNode *next;  6  * ListNode(int x) : val(x), next(NULL) {}  7  * };  8  */
 9 class Solution { 10 public: 11     //好奇怪,爲啥這裏要寫大於符號,pq纔是從小到大排序... ????
12     struct cmp{ 13         bool operator() (const ListNode* node1, const ListNode* node2) { 14             return node1->val > node2->val; 15  } 16  }; 17 
18     ListNode* mergeKLists(vector<ListNode*>& lists) { 19         const int n = lists.size(); 20         if (n == 0) {return NULL;} 21         vector<ListNode*> ptr(n, NULL); 22         for (int i = 0; i < n; ++i) { 23             ptr[i] = lists[i]; 24  } 25         ListNode *head = 0, *tail = 0; 26         priority_queue<ListNode*, vector<ListNode*>, cmp> pq; 27         for (int i = 0; i < n; ++i) { 28             if (!ptr[i]) {continue;} //注意這裏有可能有的鏈表頭節點爲空,要特判
29  pq.push(ptr[i]); 30             ptr[i] = ptr[i]->next; 31  } 32         while (!pq.empty()) { 33             ListNode* node = pq.top(); 34  pq.pop(); 35             if (node->next) { pq.push(node->next); } 36             if (!head) { 37                 tail = head = node; 38             } else { 39                 tail = tail->next = node; 40  } 41  } 42         return head; 43  } 44 };
View Code

 

【24】Swap Nodes in Pairs (2018年12月1日,第一次複習,沒有ko,須要再次複習)

給了一個鏈表,交換兩個相鄰的元素。

Given 1->2->3->4, you should return the list as 2->1->4->3. 
 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* swapPairs(ListNode* head) {
12         if (!head) {return head;}
13         ListNode* pre = 0, *cur1 = head, *cur2 = cur1->next, *ne = 0;
14         ListNode* h1 = 0;
15         while (cur2) {
16             ne = cur2->next;
17             cur2->next = cur1;
18             cur1->next = ne;
19             pre = cur1;
20             if (!h1) {h1 = cur2;}
21             cur1 = ne;
22             cur2 = cur1 == nullptr ? nullptr : cur1->next;
23             pre->next = cur2 == nullptr ? cur1 : cur2;
24         }
25         return h1 == nullptr ? head : h1;
26     }
27 };
View Code

 

【25】Reverse Nodes in k-Group ()

 

【61】Rotate List (2018年12月1日,第一次複習,ko,注意邊界條件,k = 0 的狀況特判)

把一個單鏈表循環左移k個單位,返回新鏈表。

Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
Explanation:
rotate 1 steps to the right: 2->0->1->NULL
rotate 2 steps to the right: 1->2->0->NULL
rotate 3 steps to the right: 0->1->2->NULL
rotate 4 steps to the right: 2->0->1->NULL

題解:先走到要左移的第k個結點的前面一個結點,這個結點就是尾部結點,而後把下一個結點看成頭結點,作幾個指針的賦值操做。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* rotateRight(ListNode* head, int k) {
12         //1. 先求長度
13         int len = getLen(head);
14         if (len == 0 || k ==0) {return head;}
15         if (k >= len) { k %= len; }
16         if (k == 0) {return head;}
17         //2. 計算應該往前走幾步
18         int step = len - k -1;
19         ListNode* cur = head;
20         for (int i = 0; i < step; ++i) {
21             cur = cur->next;
22         }
23         //3. 標記頭尾指針。尾指針就是走了step步的結點cur,頭指針是cur的next結點。
24         ListNode* tail = cur, *h1 = cur->next;
25         tail->next = 0;
26         cur = h1;
27         while (cur->next) {
28             cur = cur->next;
29         }
30         cur->next = head;
31         return h1;
32     }
33     int getLen(ListNode* head) {
34         int ret = 0;
35         ListNode* cur = head;
36         while (cur) {
37             ret++;
38             cur = cur->next;
39         }
40         return ret;
41     }
42 };
View Code

 

【82】Remove Duplicates from Sorted List II (2018年12月1日,第一次複習,有邊界沒有想到)

刪除一個鏈表裏面的重複結點,(重複結點不保留),返回頭結點。

題解:用一個cnt變量記錄當前結點出現了幾回,若是隻出現一次就把在加上。有個小的解題點須要注意,就是若是輸入是 [1,2,2] 這種的話,最後的尾結點不是最後的結點這種,每次都要執行 tail->next = 0,來避免這種case。 

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* deleteDuplicates(ListNode* head) {
12         ListNode *h1 = 0, *tail = 0;
13         ListNode *pre = head, *cur = head;
14         while (pre) {
15             cur = pre->next;
16             int cnt = 1;  //用一個變量標記當前結點有幾個重複的
17             while (pre && cur && pre->val == cur->val) {
18                 cur = cur->next;
19                 ++cnt;
20             }
21             if (cnt == 1) {
22                 if (!h1) {
23                     tail = h1 = pre;
24                 } else {
25                     tail = tail->next = pre;
26                 }
27                 tail->next = 0;  //若是當前結點後面有一堆重複的數的話,那麼其實當前結點就是尾結點 [1,2,2]
28             }
29             if (cur) { 
30                 pre = cur; 
31             } else {
32                 pre = 0;
33             }
34         }
35         return h1;
36     }
37 };
View Code

 

【83】Remove Duplicates from Sorted List (2018年12月1日,第一次複習,ko)

刪除一個鏈表裏面的重複結點(重複結點保留一個,目標是全部結點distinct),返回頭結點。

題解:用兩根指針遍歷,pre指針保存第一次出現的當前元素,cur指針一直日後遍歷,直到下一個第一次出現的元素。 

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* deleteDuplicates(ListNode* head) {
12         ListNode *h1 = head;
13         ListNode *pre = head, *cur = head, *ne = 0;
14         while (cur) {
15             cur = cur->next;
16             while (pre && cur && pre->val == cur->val) {
17                 cur = cur->next;
18             }
19             pre->next = cur;
20             pre = cur;
21         }
22         return h1;
23     }
24 };
View Code

 

【86】Partition List (2018年12月1日,第一次複習,寫的有bug,須要二次複習)

把單向鏈表按給定的值 x 劃分紅小於x的結點在左邊,大於等於 x 的結點在右邊的樣子。

題解:(相似題)把一個數組按照給定的值 x 劃分紅左邊小,中間相等,右邊大的樣子。(這個題叫作荷蘭國旗問題,也是快速排序的 partition)。

說回這道題,我先把鏈表拆成兩個,一個是小於 x 的值的鏈表,一個是大於等於 x 值的鏈表(拆的時候注意執行 tail->next = 0 的時候,下一個結點必定要用指針提早標記起來,否則下一個結點就丟了)。而後把這兩個鏈接起來就ok了。 

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* partition(ListNode* head, int x) {
12         vector<ListNode*> h(2, nullptr);
13         vector<ListNode*> tail(2, nullptr);
14         ListNode* cur = head, *ne = 0;
15         while (cur) {
16             ne = cur->next;  //先用一個指針標記下一個結點,否則執行 tail[i]->next = 0 的時候至關於 cur->next = 0。
17             if (cur->val < x) {
18                 if (!h[0]) {
19                     tail[0] = h[0] = cur;
20                 } else {
21                     tail[0] = tail[0]->next = cur;
22                 }
23                 tail[0]->next = 0;
24             } else {
25                 if (!h[1]) {
26                     tail[1] = h[1] = cur;
27                 } else {
28                     tail[1] = tail[1]->next = cur;
29                 }
30                 tail[1]->next = 0;
31             }
32             cur = ne;  
33         }
34         ListNode* ret = 0, *t = 0;
35         for (int i = 0; i < 2; ++i) {
36             if (!h[i]) {continue;}
37             if (!ret) {
38                 ret = h[i];
39                 t = tail[i];
40             } else {
41                 t->next = h[i];
42                 t = tail[i];
43             }
44         }
45         return ret;
46     }
47 };
View Code

 

【92】Reverse Linked List II (2018年12月1日,第一次複習,須要調試)

把單鏈表上的第 m 個結點到第 n 個結點這一部分進行反轉,m,n是整數,1 ≤ m ≤ n ≤ length of list.

Example:
Input: 1->2->3->4->5->NULL, m = 2, n = 4
Output: 1->4->3->2->5->NULL

題解:本題須要分類其實,我一開始只想了最普通那種,當 m 不等於 1 的時候,這個時候至關於我先走了 m-1 步,用一個指針標記第 m 個結點的前一個結點,而後從第 m 個結點開始反轉 k 個結點(k = n-m+1)。

然而當 m =1 的時候至關於反轉整個鏈表,須要分類處理。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* reverseBetween(ListNode* head, int m, int n) {
12         const int k = n - m + 1;
13         ListNode* newHead = 0;
14         if (m == 1) {
15             newHead = reverse(&head, k);
16         } else {
17             ListNode* cur = head;
18             for (int i = 1; i < m-1; ++i) {
19                 cur = cur->next;
20             }
21             ListNode* pre = cur;
22             pre->next = reverse(&cur->next, k);
23             newHead = head;
24         }
25         return newHead;
26     }
27     ListNode* reverse(ListNode** head, const int k) {
28         ListNode *pre = 0, * cur = *head, * ne = 0;
29         ListNode *tail = 0;
30         for (int i = 0; i < k && cur; ++i) {
31             ne = cur->next;
32             cur->next = pre;
33             pre = cur;
34             if (!tail) {tail = cur;}
35             cur = ne;
36         } 
37         tail->next = cur;
38         return pre;
39     }
40     
41 };
View Code

 

【109】Convert Sorted List to Binary Search Tree (2018年12月1日,第一次複習,WA了一次)

把一個有序的鏈表拍成一棵高度平衡的二叉樹。

Example:
Given the sorted linked list: [-10,-3,0,5,9],
One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:
      0
     / \
   -3   9
   /   /
 -10  5

題解:咱們先用快慢指針找到鏈表中間的結點,(若是是奇數個結點就指向中心的結點,若是是偶數個結點就指向中間兩個結點中靠後的那個結點,這樣生成的左子樹可能比右子樹高度多1)。而後把中間結點看成根結點。遞歸生成左右子樹。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 /**
10  * Definition for a binary tree node.
11  * struct TreeNode {
12  *     int val;
13  *     TreeNode *left;
14  *     TreeNode *right;
15  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
16  * };
17  */
18 class Solution {
19 public:
20     TreeNode* sortedListToBST(ListNode* head) {
21         if (!head) {return nullptr;}
22         ListNode* slow = head, *fast = head;
23         ListNode* pre = 0;
24         while (fast && fast->next) {
25             pre = slow;
26             slow = slow->next;
27             fast = fast->next->next;
28         }
29         TreeNode* root = new TreeNode(slow->val);
30         if (pre) {pre->next = 0;}
31         if (pre != 0) {  //若是隻有單個結點的話,再次調用生成左子樹沒有任何意義。
32             root->left = sortedListToBST(head);
33         }
34         root->right = sortedListToBST(slow->next);
35         return root;
36     }
37 };
View Code

 

【138】Copy List with Random Pointer (2018年12月1日,第一次複習)

複製含有隨機指針結點的鏈表。一種特殊的鏈表結點類描述以下:

//Definition for singly-linked list with a random pointer.
struct RandomListNode {
    int label;
    RandomListNode *next, *random;
    RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
};

rand指針是ListNode類中新增的指針,這個指針可能指向整個鏈表中的任何一個結點,也可能指向 null, 給定有這種種類的節點組成的鏈表頭部,請完成該鏈表的拷貝。

題解:解法一:能夠用 map 標記。相似於這種結構 ({1 -> 1'}, {2 -> 2'}, {3->3'})。

解法二:把新拷貝的結點放在原始結點的後面,就是相似於 1 -> 1' -> 2 -> 2' -> 3 -> 3'。而後把 rand 指針串好。在把新舊鏈表分離出來(本題就要求原來鏈表出去的時候不能被改變)。

 1 /**
 2  * Definition for singly-linked list with a random pointer.
 3  * struct RandomListNode {
 4  *     int label;
 5  *     RandomListNode *next, *random;
 6  *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     RandomListNode *copyRandomList(RandomListNode *head) {
12         if (!head) {return head;}
13         //1. copy list without rand ptr
14         RandomListNode *cur = head, *ne = 0;
15         while (cur) {
16             ne = cur->next;
17             RandomListNode* node = new RandomListNode(cur->label);
18             cur->next = node;
19             node->next = ne;
20             cur = ne;
21         }
22         //2. copy rand ptr
23         cur = head, ne = 0;
24         while (cur) {
25             ne = cur->next->next;
26             if (cur->random) {
27                 cur->next->random = cur->random->next;
28             }
29             cur = ne;
30         }
31         //3. split listnode, should recover ori listnode
32         cur = head;
33         RandomListNode* h1 = 0, *t1 = 0;
34         RandomListNode* h2 = 0, *t2 = 0;
35         while (cur) {
36             ne = cur->next->next;
37             if (!h1 && !h2) {
38                 t1 = h1 = cur->next;
39                 t2 = h2 = cur;
40             } else {
41                 t1 = t1->next = cur->next;
42                 t2 = t2->next = cur;
43             }
44             t1->next = 0;
45             t2->next = 0;
46             cur = ne;
47         }
48         head = h2;
49         return h1;
50     }
51 };
View Code

 

【141】Linked List Cycle (2019年2月20日)

判斷一個linkedlist是否是有環。

題解:快慢指針。若是快慢指針可以相遇,就是有環。不然沒有。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     bool hasCycle(ListNode *head) {
12         if (!head) {return false;}
13         ListNode *slow = head, *fast = head;
14         while (fast && fast->next) {
15             slow = slow->next;
16             fast = fast->next->next;
17             if (slow == fast) {
18                 return true;
19             }
20         }
21         return false;
22     }
23 };
View Code

 

【142】Linked List Cycle II (2019年2月20日)

判斷一個linkedlist是否是有環,若是有環的話,返回環的起點。

題解:算法是先讓快慢指針相遇,相遇以後慢指針回到頭結點,而後兩根指針同時走一步,再次相遇就是環的起點。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 //算法是先讓快慢指針相遇,相遇以後慢指針回到頭結點,而後兩根指針同時走一步,再次相遇就是環的起點。
10 class Solution {
11 public:
12     ListNode *detectCycle(ListNode *head) {
13         if (!head) {return nullptr;}
14         ListNode *slow = head, *fast = head;
15         while (fast && fast->next) {
16             slow = slow->next;
17             fast = fast->next->next;
18             if (slow == fast) {
19                 slow = head;
20                 while (slow != fast) {
21                     slow = slow->next;
22                     fast = fast->next;
23                 }
24                 return slow;
25             }
26         }
27         return nullptr;
28     }
29 };
View Code

 

【143】Reorder List (2018年12月1日,第一次review,ko) 

Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… 

Example 1:
Given 1->2->3->4, reorder it to 1->4->2->3.
Example 2:
Given 1->2->3->4->5, reorder it to 1->5->2->4->3.

題解:先按照快慢指針拆分紅兩個鏈表,reverse 後面半個鏈表,而後再拼起來。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     void reorderList(ListNode* head) {
12         if (!head) {return;}
13         ListNode* slow = head, *fast = head, *pre = 0;
14         while (fast && fast->next) {
15             pre = slow;
16             slow = slow->next;
17             fast = fast->next->next;
18         }
19         if (fast && !fast->next) { //奇數個結點
20             pre = slow;
21             slow = slow->next;
22         }
23         pre->next = 0;
24         ListNode* cur2 = reverse(slow), *cur1 = head;
25         if (!cur2) {return;}  //只有一個結點
26         ListNode *h1 = 0, *t1 = 0;
27         while (cur1 && cur2) {
28             if (!h1) {
29                 t1 = h1 = cur1;
30                 cur1= cur1->next;
31             } else {
32                 t1 = t1->next = cur1;
33                 cur1 = cur1->next;
34             }
35             t1 = t1->next = cur2;
36             cur2 = cur2->next;
37         }
38         if (cur1) {
39             t1 = t1->next = cur1;
40         } else if (cur2) {
41             t1= t1->next = cur2;
42         }
43         head = h1;
44         return;   
45     }
46     ListNode* reverse(ListNode* head) {
47         ListNode *pre = 0, *cur = head, *ne = 0;
48         while (cur) {
49             ne = cur->next;
50             cur->next = pre;
51             pre = cur;
52             cur = ne;
53         }
54         return pre;
55     }
56 };
View Code

 

【147】Insertion Sort List 

 

【148】Sort List 

 

【160】Intersection of Two Linked Lists (2018年12月1日,第一次review, ko)

找到兩個鏈表的公共部分的第一個結點。沒有公共部分返回空結點。

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

題解:分別獲取兩個鏈表的長度,讓長的那個鏈表走的和短的同樣長的位置,而後兩個一塊兒走。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
12         int l1 = getLen(headA), l2 = getLen(headB);
13         int diff = 0;
14         ListNode *cur1 = headA, *cur2 = headB;
15         if (l1 > l2) {
16             diff = l1 - l2;
17             for (int i = 0; i < diff; ++i) {
18                 cur1 = cur1->next;
19             }
20         } else if (l1 < l2) {
21             diff = l2 - l1;
22             for (int i = 0; i < diff; ++i) {
23                 cur2 = cur2->next;
24             }
25         }
26         while (cur1 && cur2) {
27             if (cur1 == cur2) {
28                 return cur1;
29             }
30             cur1 = cur1->next;
31             cur2 = cur2->next;
32         }
33         return nullptr;
34     }
35     int getLen(ListNode* head) {
36         ListNode* cur = head;
37         int cnt = 0;
38         while (cur) {
39             cur = cur->next;
40             cnt++;
41         }
42         return cnt;
43     }
44 };
View Code

 

【203】Remove Linked List Elements 

 

【206】Reverse Linked List (2019年2月24日)

反轉一個鏈表。

題解:使用 recursive方法 和 iterative方法。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* reverseList(ListNode* head) {
12         if (!head || !head->next) { return head; }
13         ListNode* nextNode = head->next;
14         ListNode* newHead = reverseList(nextNode);
15         nextNode->next = head;
16         head->next = nullptr;
17         return newHead;
18     }
19 };
View Code
 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* reverseList(ListNode* head) {
12         ListNode *pre=0, *cur=head, *ne=0;
13         while(cur){
14             ne = cur->next;
15             cur->next = pre;
16             pre = cur;
17             cur = ne;
18         }
19         return pre;
20     }
21 };
View Code

 

【234】Palindrome Linked List 

 

【237】Delete Node in a Linked List 

 

【328】Odd Even Linked List 

 

【369】Plus One Linked List   (2018 年11月26日)

給一個頭結點是高位數字的鏈表整數加一。返回新鏈表。

題解:普通解法能夠先搞成一個string 或者vector,再作高精度加。我是先翻轉鏈表,而後加一,而後再翻轉一次。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* plusOne(ListNode* head) {
12         if (!head) {return head;}
13         h1 = head;
14         h1 = reverseListNode();
15         ListNode* cur = h1, *pre = 0;
16         int carry = 0;
17         while (carry == 1 && cur || cur == h1) {
18             int num = cur == h1 ? cur->val + 1 : carry + cur->val;
19             cur->val = num % 10;
20             carry = num / 10;
21             pre = cur;
22             cur = cur->next;
23         }
24         if (carry) {
25             pre->next = new ListNode(carry);
26         }
27         h1 = reverseListNode();
28         return h1;
29     }
30     ListNode* h1;
31     ListNode* reverseListNode() {
32         if (!h1) {return h1;}
33         ListNode* pre = 0, *cur = h1, *next = cur->next;
34         while (cur) {
35             next = cur->next;
36             cur->next = pre;
37             pre = cur;
38             cur = next;
39         }
40         return pre;
41     }
42 };
View Code

 

【379】Design Phone Directory 

 

【426】Convert Binary Search Tree to Sorted Doubly Linked List 

 

【430】Flatten a Multilevel Doubly Linked List 

 

【445】Add Two Numbers II (2018年11月26日)

給了兩個鏈表,每一個鏈表表明一個數,頭結點表明最高位的數字,求兩個鏈表的累加和,返回一個鏈表。(題目要求不能翻轉鏈表)

Follow up:
What if you cannot modify the input lists? In other words, reversing the lists is not allowed.

Example:
Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 8 -> 0 -> 7

題解:我是分別遍歷兩個鏈表,而後存在了兩個string裏面,string裏面作高精度加法。而後把結果的string再搞成一個鏈表,返回。(也能夠把string搞成vector,同樣的)

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
12         if (l1 == nullptr || l2 == nullptr) {
13             return l1 == nullptr ? l2 : l1;
14         }
15         string s1 = List2Str(l1), s2 = List2Str(l2);
16         string s3 = addString(s1, s2);
17         ListNode *head = 0, *tail = 0;
18         for (int i = 0; i < s3.size(); ++i) {
19             ListNode* node = new ListNode((s3[i] - '0'));
20             if (!head) {
21                 tail = head = node;
22             } else {
23                 tail = tail->next = node;
24             }
25         }
26         return head;
27     }
28     string List2Str(ListNode* head) {
29         ListNode* h1 = head;
30         string ret = "";
31         while (h1) {
32             ret += to_string(h1->val);
33             h1 = h1->next;
34         }
35         return ret;
36     }
37     string addString(const string& s1, const string& s2) {
38         int carry = 0;
39         string ret = "";
40         int size = min(s1.size(), s2.size());
41         int s1size = s1.size(), s2size = s2.size();
42         for (int k = 1; k <= size; ++k) {
43             int num = (s1[s1size-k] - '0') + (s2[s2size-k] - '0') + carry;
44             string str = to_string(num % 10);
45             carry = num / 10;
46             ret =  str + ret;
47         }
48         if (size < s1size) {
49             const int leftsize = s1size - size;
50             for (int i = leftsize - 1; i >= 0; --i) {
51                 int num = (s1[i] - '0') + carry;
52                 string str = to_string(num % 10);
53                 carry = num / 10;
54                 ret = str + ret;
55             }
56         } else if (size < s2size) {
57             const int leftsize = s2size - size;
58             for (int i = leftsize - 1; i >= 0; --i) {
59                 int num = (s2[i] - '0') + carry;
60                 string str = to_string(num % 10);
61                 carry = num / 10;
62                 ret = str + ret;
63             }
64         }
65         if (carry) {
66             ret = to_string(carry) + ret;
67         }
68         return ret;
69     }
70 };
View Code

 

【707】Design Linked List 

 

【708】Insert into a Cyclic Sorted List 

 

【725】Split Linked List in Parts (2018年11月26日)

把一個鏈表分解成 k 個parts, 要求每一個 parts 均勻分佈,就是任意兩個部分之間的長度不能相差大於一。

Return a List of ListNode's representing the linked list parts that are formed.
Examples 1->2->3->4, k = 5 // 5 equal parts [ [1], [2], [3], [4], null ]
Example 1:
Input: 
root = [1, 2, 3], k = 5
Output: [[1],[2],[3],[],[]]
Explanation:
The input and each element of the output are ListNodes, not arrays.
For example, the input root has root.val = 1, root.next.val = 2, \root.next.next.val = 3, and root.next.next.next = null.
The first element output[0] has output[0].val = 1, output[0].next = null.
The last element output[4] is null, but it's string representation as a ListNode is [].
Example 2:
Input: 
root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = 3
Output: [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
Explanation:
The input has been split into consecutive parts with size difference at most 1, and earlier parts are a larger size than the later parts.

題解:先算總長度,而後把每一個部分最短的長度算出來base,再把有幾個部分須要加一算出來addition,而後開始分解就好啦。主要注意分解完了以後tail->next  要指向空指針。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     vector<ListNode*> splitListToParts(ListNode* root, int k) {
12         vector<ListNode*> ret;
13         int n = getLen(root);
14         int base = n / k;
15         int addition = n % k;
16         ListNode* head = root;
17         for (int i = 0; i < addition; ++i) { //base + 1
18             const int tot = base + 1;
19             ListNode *h1 = 0, *t1 = 0;
20             for (int j = 0; j < tot; ++j) {
21                 if (h1 == 0) {
22                     t1 = h1 = head;
23                 } else {
24                     t1 = t1->next = head;
25                 }
26                 head = head->next;
27             }
28             if(t1) {t1->next = 0;}
29             ret.push_back(h1);
30         }
31         for (int i = 0; i < k - addition; ++i) { //base
32             const int tot = base;
33             ListNode* h1 = 0, *t1 = 0;
34             for (int j = 0; j < tot; ++j) {
35                 if (h1 == 0) {
36                     t1 = h1 = head;
37                 } else {
38                     t1 = t1->next = head;
39                 }
40                 head = head->next;
41             }
42             if (t1) {t1->next = 0;}
43             ret.push_back(h1);
44         }
45         return ret;
46     }
47     int getLen(ListNode* root) {
48         ListNode* head = root;
49         if (!head) {return 0;}
50         int ret = 0;
51         while (head) {
52             ret++;
53             head = head->next;
54         }
55         return ret;
56     }
57     /*
58     void print(ListNode* h1) {
59         ListNode* head = h1;
60         while (head) {
61             printf("%d -> ", head->val);
62             head = head->next;
63         }
64     }
65     */
66 };
View Code

 

【817】Linked List Components (2019年2月9日,谷歌tag複習)(M)

給了一個鏈表和一個集合G(G是鏈表元素的子集),若是在鏈表中兩個相鄰的元素算一個component,返回這個集合G中有多少個component。

題解:遍歷鏈表,若是當前的結點在G中的話,若是沒有component的頭結點,就把當前結點看成一個component的頭結點,若是有就繼續遍歷。若是當前結點不在G中的話,說明前面的component已經結束,把father清空。

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     int numComponents(ListNode* head, vector<int>& G) {
12         if (!head) {return 0;}
13         set<int> st(G.begin(), G.end());
14         int cnt = 0;
15         ListNode *cur = head, *father = nullptr;
16         while (cur) {
17             if (st.find(cur->val) == st.end()) {
18                 father = nullptr;
19             } else {
20                 if (!father) {
21                     father = cur;
22                     cnt++;
23                 } 
24             }
25             cur = cur->next;
26         }
27         return cnt;
28     }
29 };
View Code

 

【876】Middle of the Linked List

相關文章
相關標籤/搜索