常用操作

  1. class MyLinkedList
  2. {
  3. public:
  4. struct ListNode
  5. {
  6. int val;
  7. ListNode *next;
  8. ListNode() : val(0), next(nullptr) {}
  9. ListNode(int x) : val(x), next(nullptr) {}
  10. ListNode(int x, ListNode *next) : val(x), next(next) {}
  11. };
  12. ListNode* head;
  13. int cnt;
  14. MyLinkedList()
  15. {
  16. cnt = 0;
  17. head = nullptr;
  18. }
  19. int get(int index)
  20. {
  21. if(index<0 || index>=cnt) return -1;
  22. ListNode *p = head;
  23. while(p)
  24. {
  25. if(index-- == 0) return p->val;
  26. p = p->next;
  27. }
  28. }
  29. void addAtHead(int val)
  30. {
  31. ListNode* p = new ListNode(val);
  32. p->next = head;
  33. head = p;
  34. cnt++;
  35. }
  36. void addAtTail(int val)
  37. {
  38. cnt++;
  39. if(!head)
  40. {
  41. head = new ListNode(val);
  42. return ;
  43. }
  44. ListNode* p = head;
  45. while(p->next)
  46. {
  47. p = p->next;
  48. }
  49. p->next = new ListNode(val);
  50. return ;
  51. }
  52. void addAtIndex(int index, int val)
  53. {
  54. if(index>cnt) return;
  55. if(index<=0)
  56. {
  57. addAtHead(val);
  58. return ;
  59. }
  60. if(index == cnt)
  61. {
  62. addAtTail(val);
  63. return ;
  64. }
  65. ListNode* p = head;
  66. cnt++;
  67. while(p->next)
  68. {
  69. if(--index == 0)
  70. {
  71. p->next = new ListNode(val,p->next);
  72. return ;
  73. }
  74. p = p->next;
  75. }
  76. return ;
  77. }
  78. void deleteAtIndex(int index)
  79. {
  80. if(index<0 || index>=cnt) return ;
  81. cnt--;
  82. if(index == 0)
  83. {
  84. head = head->next;
  85. return ;
  86. }
  87. ListNode* p = head;
  88. while(p->next)
  89. {
  90. if(--index == 0)
  91. {
  92. p->next = p->next->next;
  93. return ;
  94. }
  95. p = p->next;
  96. }
  97. }
  98. void pfList()
  99. {
  100. cout<<"cnt:"<<cnt<<endl;
  101. ListNode* p = head;
  102. while(p)
  103. {
  104. cout<<p->val<<' ';
  105. p = p->next;
  106. }
  107. cout<<endl;
  108. return ;
  109. }
  110. };

翻转链表

  1. class Solution {
  2. public:
  3. ListNode* reverseList(ListNode* head) {
  4. ListNode* p = head;
  5. ListNode* post;
  6. ListNode* pre = nullptr;
  7. while(p) {
  8. post = p->next;
  9. p->next = pre;
  10. pre = p;
  11. p = post;
  12. }
  13. head = pre;
  14. return head;
  15. }
  16. };

删除倒数第n个节点(双指针法+哑巴节点)

  1. class Solution {
  2. public:
  3. ListNode* removeNthFromEnd(ListNode* head, int n) {
  4. ListNode* dummy = new ListNode(0, head);
  5. ListNode* first = head;
  6. ListNode* second = dummy;
  7. for (int i = 0; i < n; ++i) {
  8. first = first->next;
  9. }
  10. while (first) {
  11. first = first->next;
  12. second = second->next;
  13. }
  14. second->next = second->next->next;
  15. ListNode* ans = dummy->next;
  16. delete dummy;
  17. return ans;
  18. }
  19. };

链表相交

注意相交的节点之后都是同一节点了,也就是后面的都合并了
一种做法是统计长度,然后从短的开始同时遍历,还有一种比较巧妙的解法是a+c+b+c=b+c+a+c:

  1. class Solution {
  2. public:
  3. ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
  4. ListNode* h1 = headA;
  5. ListNode* h2 = headB;
  6. while(h1 != h2){
  7. h1 = (h1 == nullptr ? headB : h1->next);
  8. h2 = (h2 == nullptr ? headA : h2->next);
  9. }
  10. return h1;
  11. }
  12. };

环形链表

可以使用快慢指针法, 分别定义 fast 和 slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。因为如果有环的话,相当于fast一个节点一个节点地追slow。
如何找到环的入口点?fast和slow相遇后的点设为index1,链表起始点设为index2,index1和2继续往后遍历必相遇,这时的相遇点就是环的入口。

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