一、

1. Remove Duplicates from Sorted List II

  1. class Solution {
  2. public:
  3. ListNode* deleteDuplicates(ListNode* head) {
  4. ListNode* dummy = new ListNode();
  5. dummy->next = head;
  6. ListNode* pre = dummy;
  7. ListNode* cur = head;
  8. while (cur != NULL && cur->next != NULL) {
  9. if (cur->val == cur->next->val) {
  10. while(cur->next != NULL && cur->val == cur->next->val) {
  11. cur = cur->next;
  12. }
  13. pre->next = cur->next;
  14. cur = cur->next;
  15. } else {
  16. pre = pre->next;
  17. cur = cur->next;
  18. }
  19. }
  20. return dummy->next;
  21. }
  22. };

2. Remove Duplicates from Sorted List

  1. class Solution {
  2. public:
  3. ListNode* deleteDuplicates(ListNode* head) {
  4. ListNode* dummy = new ListNode();
  5. dummy->next = head;
  6. ListNode* pre = dummy, *cur = head;
  7. while (cur != NULL && cur->next != NULL) {
  8. if (cur->val == cur->next->val) {
  9. while (cur->next != NULL && cur->val == cur->next->val) {
  10. cur = cur->next;
  11. }
  12. pre->next = cur;
  13. pre = pre->next;
  14. cur = cur->next;
  15. } else {
  16. cur = cur->next;
  17. pre = pre->next;
  18. }
  19. }
  20. return dummy->next;
  21. }
  22. };

只在1.的基础上改了两句。

二、

1. Reverse Linked List 【模板式】

  1. ListNode* reverseList(ListNode* head) {
  2. ListNode* prev = NULL;
  3. while (head != NULL) {
  4. ListNode* next = head->next;
  5. head->next = prev;
  6. prev = head;
  7. head = next;
  8. }
  9. return prev;
  10. }

while循环里和swap很像,上一句的右侧都是下一句的左侧。

2. Reverse Linked List II

  1. class Solution {
  2. public:
  3. ListNode* reverseBetween(ListNode* head, int m, int n) {
  4. ListNode* dummy = new ListNode();
  5. dummy->next = head;
  6. ListNode* prev = dummy;
  7. for (int i = ; i < m; i++) {
  8. prev = prev->next;
  9. }
  10. head = prev->next;
  11. ListNode* next = head->next;
  12. ListNode* pprev = prev;
  13. ListNode* tail = head;
  14. for (int i = m; i <= n; i++) { //这部分和reverseList一样
  15. next = head->next;
  16. head->next = prev;
  17. prev = head;
  18. head = next;
  19. }
  20. pprev->next = prev;
  21. tail->next = head;
  22. return dummy->next;
  23. }
  24. };

中间(m, n)区间内reverse和1.里reverseList一样。

注意:从m到n这几个元素都参与for循环了,包括第m个元素!进行reverse之后,head指向第n+1个元素,prev指向逆转后的新head(从m到n这几个元素中的新head)。

Partition List

  1. class Solution {
  2. public:
  3. ListNode* partition(ListNode* head, int x) {
  4. ListNode* leftDummy = new ListNode();
  5. ListNode* rightDummy = new ListNode();
  6. ListNode* left = leftDummy, *right = rightDummy;
  7. while (head != NULL) {
  8. if (head->val < x) {
  9. left->next = head;
  10. left = left->next;
  11. } else {
  12. right->next = head;
  13. right = right->next;
  14. }
  15. head = head->next;
  16. }
  17. right->next = NULL;
  18. left->next = rightDummy->next;
  19. return leftDummy->next;
  20. }
  21. };

Merge Two Sorted Lists

  1. class Solution {
  2. public:
  3. ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
  4. ListNode* dummy = new ListNode();
  5. ListNode* pre = dummy;
  6. while (l1 != NULL && l2 != NULL) {
  7. if (l1->val < l2->val) {
  8. pre->next = l1;
  9. l1 = l1->next;
  10. } else {
  11. pre->next = l2;
  12. l2 = l2->next;
  13. }
  14. pre = pre->next;
  15. }
  16. if (l1 != NULL) {
  17. pre->next = l1;
  18. }
  19. if (l2 != NULL) {
  20. pre->next = l2;
  21. }
  22. return dummy->next;
  23. }
  24. };

Sort List

用MergeSort和QuickSort分别实现一下。

MergeSort用到了findMedian的方法(利用双指针可以达到one-pass找到中点)。

  1. class Solution {
  2. public:
  3. ListNode* findMiddle(ListNode* head) { // 找到的是下标为(n - 1) / 2的点(如果是偶数个数,那就是中间偏左一点的)
  4. ListNode* slow = head, *fast = head->next;
  5. while (fast != NULL && fast->next != NULL) {
  6. slow = slow->next;
  7. fast = fast->next->next;
  8. }
  9. return slow;
  10. }
  11. ListNode* merge(ListNode* l1, ListNode* l2) {
  12. ListNode* dummy = new ListNode();
  13. ListNode* pre = dummy;
  14. while (l1 != NULL && l2 != NULL) {
  15. if (l1->val < l2->val) {
  16. pre->next = l1;
  17. l1 = l1->next;
  18. } else {
  19. pre->next = l2;
  20. l2 = l2->next;
  21. }
  22. pre = pre->next;
  23. }
  24. if (l1 != NULL) {
  25. pre->next = l1;
  26. }
  27. if (l2 != NULL) {
  28. pre->next = l2;
  29. }
  30. return dummy->next;
  31. }
  32.  
  33. ListNode* sortList(ListNode* head) {
  34. if (head == NULL || head->next == NULL) {
  35. return head;
  36. }
  37. ListNode* mid = findMiddle(head);
  38. ListNode* right = sortList(mid->next);
  39. mid->next = NULL;
  40. ListNode* left = sortList(head);
  41. return merge(left, right);
  42. }
  43. };

其中merge即为上一题中的mergeTwoLists.

注意:findMiddle函数最开始时slow = head, fast = head->next. 通过这种方式可以保证求出来的mid是当有偶数个元素时是中间偏左一点的。

Reorder List

【三大链表基本操作:findMiddle,reverse,merge】

  1. class Solution {
  2. public:
  3. ListNode* findMiddle(ListNode* head) {
  4. ListNode* slow = head, *fast = head;
  5. while (fast != NULL && fast->next != NULL) {
  6. slow = slow->next;
  7. fast = fast->next->next;
  8. }
  9. return slow;
  10. }
  11. ListNode* reverseList(ListNode* head) {
  12. ListNode* prev = NULL;
  13. while (head != NULL) {
  14. ListNode* next = head->next;
  15. head->next = prev;
  16. prev = head;
  17. head = next;
  18. }
  19. return prev;
  20. }
  21. ListNode* merge(ListNode* l1, ListNode* l2) {
  22. ListNode* dummy = new ListNode();
  23. ListNode* prev = dummy;
  24. int count = ;
  25. while (l1 != NULL && l2 != NULL) {
  26. count++;
  27. if (count % == ) {
  28. prev->next = l1;
  29. l1 = l1->next;
  30. } else {
  31. prev->next = l2;
  32. l2 = l2->next;
  33. }
  34. prev = prev->next;
  35. }
  36. if (l1 != NULL) {
  37. prev->next = l1;
  38. } else {
  39. prev->next = l2;
  40. }
  41. return dummy->next;
  42. }
  43. void reorderList(ListNode* head) {
  44. if (head == NULL || head->next == NULL) {
  45. return;
  46. }
  47. ListNode* mid = findMiddle(head);
  48. ListNode* p = reverseList(mid->next);
  49. mid->next = NULL;
  50. merge(head, p);
  51. }
  52. };

Merge k Sorted Lists

方法1: 利用堆(priority_queue)。每次取出K个队列中的最小值(logK),共取N次,因此复杂度为 NlogK

  1. class Solution {
  2. public:
  3. struct cmp {
  4. bool operator()(ListNode* p, ListNode* q) {
  5. return p->val > q->val;
  6. }
  7. };
  8.  
  9. ListNode* mergeKLists(vector<ListNode*> &lists) {
  10. if (lists.empty()) {
  11. return NULL;
  12. }
  13. priority_queue<ListNode*, vector<ListNode*>, cmp> pq;
  14. ListNode* dummy = new ListNode();
  15. ListNode* prev = dummy;
  16. for (int i = ; i < lists.size(); i++) {
  17. if (lists[i] != NULL) {
  18. pq.push(lists[i]);
  19. }
  20. }
  21. while (!pq.empty()) {
  22. ListNode* tmp = pq.top();
  23. prev->next = tmp;
  24. prev = tmp;
  25. pq.pop();
  26. if (tmp->next != NULL) {
  27. pq.push(tmp->next);
  28. }
  29. }
  30. return dummy->next;
  31. }
  32. };

方法2:分治。【自顶向下】

  1. class Solution {
  2. public:
  3. ListNode* mergeKLists(vector<ListNode*> &lists) {
  4. if (lists.empty()) {
  5. return NULL;
  6. }
  7. return mergeHelper(lists, , lists.size() - );
  8. }
  9.  
  10. ListNode* mergeHelper(vector<ListNode*> &lists, int start, int end) {
  11. if (start == end) {
  12. return lists[start];
  13. }
  14. int mid = start + (end - start) / ;
  15. ListNode* left = mergeHelper(lists, start, mid);
  16. ListNode* right = mergeHelper(lists, mid + , end);
  17. return mergeTwoLists(left, right);
  18. }
  19.  
  20. ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
  21. ListNode* dummy = new ListNode();
  22. ListNode* prev = dummy;
  23. while (l1 != NULL && l2 != NULL) {
  24. if (l1->val < l2->val) {
  25. prev->next = l1;
  26. l1 = l1->next;
  27. } else {
  28. prev->next = l2;
  29. l2 = l2->next;
  30. }
  31. prev = prev->next;
  32. }
  33. if (l1 != NULL) {
  34. prev->next = l1;
  35. } else {
  36. prev->next = l2;
  37. }
  38. return dummy->next;
  39. }
  40. };

注意:不要忘了判空!这种边界条件要谨慎!谨记!

Linked List Cycle

  1. class Solution {
  2. public:
  3. bool hasCycle(ListNode* head) {
  4. if (head == NULL) {
  5. return false;
  6. }
  7. ListNode* slow = head, *fast = head;
  8. while (fast && fast->next) {
  9. slow = slow->next;
  10. fast = fast->next->next;
  11. if (slow == fast) {
  12. return true;
  13. }
  14. }
  15. return false;
  16. }
  17. };

Linked List Cycle II

  1. class Solution {
  2. public:
  3. ListNode* detectCycle(ListNode* head) {
  4. ListNode* slow = head, *fast = head;
  5. while (fast && fast->next) {
  6. slow = slow->next;
  7. fast = fast->next->next;
  8. if (slow == fast) {
  9. while (head != slow) {
  10. head = head->next;
  11. slow = slow->next;
  12. }
  13. return slow;
  14. }
  15. }
  16. return NULL;
  17. }
  18. };

Copy List with Random Pointer

  1. class Solution {
  2. public:
  3.  
  4. void copyNext(RandomListNode* head) {
  5. RandomListNode* pre = head;
  6. while (pre != NULL) {
  7. RandomListNode* tmp = new RandomListNode(pre->label);
  8. tmp->next = pre->next;
  9. pre->next = tmp;
  10. pre = pre->next->next;
  11. }
  12. }
  13. void copyRandom(RandomListNode* head) {
  14. RandomListNode* pre = head;
  15. while (pre != NULL) {
  16. if (pre->random != NULL) { // don't forget
  17. pre->next->random = pre->random->next;
  18. }
  19. pre = pre->next->next;
  20. }
  21. }
  22.  
  23. RandomListNode* splitList(RandomListNode* head) {
  24. RandomListNode* newHead = head->next;
  25. RandomListNode* q = newHead;
  26. while (head != NULL) {
  27. head->next = q->next;
  28. head = head->next;
  29. if (head) { // don't forget
  30. q->next = head->next;
  31. }
  32. q = q->next;
  33. }
  34. return newHead;
  35. }
  36.  
  37. RandomListNode* copyRandomList(RandomListNode* head) {
  38. if (head == NULL) {
  39. return NULL;
  40. }
  41. copyNext(head);
  42. copyRandom(head);
  43. return splitList(head);
  44. }
  45. };

注意!处理链表题很重要的一点是:在对一个指针p取next时,首先要确保 p!=NULL 

Clone Graph

Convert Sorted List to Binary Search Tree

Convert Binary Tree to Doubly Linked List

Reverse Nodes in k-Group

Heapify 堆化

=================================================

  24 Swap Nodes in Pairs 32.4% Medium
  148 22.2% Medium
  61 Rotate List 21.7% Medium
  25 25.4% Hard
  206   31.9% Easy
  92   26.0% Medium
  143   21.0% Medium
  19 Remove Nth Node From End of List 27.0% Easy
  203 Remove Linked List Elements 25.9% Easy
  83   34.5% Easy
  82   25.0% Medium
  86   27.4% Medium
  234 Palindrome Linked List 22.6% Easy
  21   32.6% Easy
  23 21.1% Hard
  141   36.3% Medium
  142   31.4% Medium
  160 Intersection of Two Linked Lists 28.7% Easy
  147 Insertion Sort List 26.6% Medium
  237 Delete Node in a Linked List 46.7% Easy
  138 25.2% Hard
  109 27.9% Medium
  2 Add Two Numbers 20.7% Medium

[剑指offer] 两个链表的第一个公共节点

  1. class Solution {
  2. public:
  3. ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
  4. ListNode* p = pHead1;
  5. int count1 = , count2 = ;
  6. while (p != NULL) {
  7. count1++;
  8. p = p->next;
  9. }
  10. p = pHead2;
  11. while (p != NULL) {
  12. count2++;
  13. p = p->next;
  14. }
  15. if (count1 < count2) {
  16. return findNode(pHead1, count1, pHead2, count2);
  17. } else {
  18. return findNode(pHead2, count2, pHead1, count1);
  19. }
  20. }
  21.  
  22. ListNode* findNode(ListNode* pHead1, int count1, ListNode* pHead2, int count2) {
  23. if (pHead1 == NULL) {
  24. return NULL;
  25. }
  26. int tmp = count2 - count1;
  27. ListNode* p2 = pHead2, *p1 = pHead1;
  28. while (tmp--) {
  29. p2 = p2->next;
  30. }
  31. while (p1 != NULL && p1 != p2) {
  32. p1 = p1->next;
  33. p2 = p2->next;
  34. }
  35. return p1;
  36. }
  37. };

参考剑指offer P193. 本题说的“公共节点”不是指“值相等”,而是“同一个节点”。即两链表在该点处汇合。

leetcode Ch5-Linked List的更多相关文章

  1. 【Leetcode】Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...

  2. [LeetCode] 141. Linked List Cycle 链表中的环

    Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using ext ...

  3. [LeetCode] 142. Linked List Cycle II 链表中的环 II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...

  4. [LeetCode] Palindrome Linked List 回文链表

    Given a singly linked list, determine if it is a palindrome. Follow up: Could you do it in O(n) time ...

  5. [LeetCode] Reverse Linked List 倒置链表

    Reverse a singly linked list. click to show more hints. Hint: A linked list can be reversed either i ...

  6. [LeetCode] Remove Linked List Elements 移除链表元素

    Remove all elements from a linked list of integers that have value val. Example Given: 1 --> 2 -- ...

  7. [LeetCode] Reverse Linked List II 倒置链表之二

    Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...

  8. Java for LeetCode 142 Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...

  9. [LeetCode] Split Linked List in Parts 拆分链表成部分

    Given a (singly) linked list with head node root, write a function to split the linked list into k c ...

  10. [LeetCode] Design Linked List 设计链表

    Design your implementation of the linked list. You can choose to use the singly linked list or the d ...

随机推荐

  1. Java:对象的强、软、弱和虚引用的区别

    1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...

  2. Chapter 3. Lexical Structure

    /** * Expression = Expression1 [ExpressionRest] * ExpressionRest = [AssignmentOperator Expression1] ...

  3. 利用css实现搜索过滤

    无意中找到一种利用css就可实现的搜索过滤的方法,不得不说看了代码之后确实被惊艳到了,亏我之前面试还因为做这个功能做太慢而拖了后腿.在此记录下代码: <!DOCTYPE html> < ...

  4. [PY3]——内置数据结构(1)——列表及其常用操作

    列表及其常用操作_xmind图         about列表 列表是一个序列,用于顺序存储数据 列表分为两种:ArrayList(用数组实现).LinkedList(用链表实现) 定义与初始化 #l ...

  5. UEditor图片焦点错位,火狐document.body.scrollTop不管用的问题

    转自 http://liyunpeng.iteye.com/blog/2068751 关于 document.body.scrollTop 在火狐浏览器中不管用的问题 看网上有人写通过判断docume ...

  6. WCF WCF的宿主

    一.WCF服务应用程序与WCF服务库 我们在平时开发的过程中常用的项目类型有“WCF 服务应用程序”和“WCF服务库”. WCF服务应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类契约的定 ...

  7. Docker学习之基本概念

    Docker学习之基本概念 作为一个后端noder,不了解docker有点说不过去,这节开始,学习一些docker层面的东西. 什么是docker Docker最初是dotCloud公司创始人Solo ...

  8. 十、spark graphx的scala示例

    简介 spark graphx官网:http://spark.apache.org/docs/latest/graphx-programming-guide.html#overview spark g ...

  9. php分页实例及其原理

    Part1:实例 /** * 取得上次的过滤条件 * @param string $param_str 参数字符串,由list函数的参数组成 * @return 如果有,返回array('filter ...

  10. MySQL一查就会

    Table1--mysql常用操作 主题 用例 说明 书写规范 数据库和表的名称不一定要大写. 输入文本类型的数据时都要加上单引号: NULL 表示未定义,它不会等于另一个NULL: 不要使用双引号. ...