ToB企服应用市场:ToB评测及商务社交产业平台

标题: 链表OJ题 [打印本页]

作者: 慢吞云雾缓吐愁    时间: 2024-6-15 03:58
标题: 链表OJ题
1. 链表的回文布局


由于单链表不能从后往前找节点,以是我们先找到中间节点,然后逆置,最后进行比力。
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. typedef struct ListNode
  4. {
  5.         int val;
  6.         struct ListNode* next;
  7. }ListNode;
  8. struct ListNode* middleNode(struct ListNode* head)
  9. {
  10.         ListNode* slow, * fast;
  11.         slow = fast = head;
  12.         while (fast && fast->next)
  13.         {
  14.                 slow = slow->next;
  15.                 fast = fast->next->next;
  16.         }
  17.         return slow;
  18. }
  19. struct ListNode* reverseList(struct ListNode* head)
  20. {
  21.         if (NULL == head)
  22.         {
  23.                 return head;
  24.         }
  25.         ListNode* n1, * n2, * n3;
  26.         n1 = NULL, n2 = head, n3 = head->next;
  27.         while (n2)
  28.         {
  29.                 n2->next = n1;
  30.                 n1 = n2;
  31.                 n2 = n3;
  32.                 if (n3)
  33.                 {
  34.                         n3 = n3->next;
  35.                 }
  36.         }
  37.         return n1;
  38. }
  39. bool chkPalindrome(ListNode* A)
  40. {
  41.         ListNode* mid = middleNode(A);
  42.         ListNode* rmid = reverseList(mid);
  43.         while (A && rmid)
  44.         {
  45.                 if (A->val != rmid->val)
  46.                 {
  47.                         return false;
  48.                 }
  49.                 A = A->next;
  50.                 rmid = rmid->next;
  51.         }
  52.         return true;
  53. }
复制代码
2. 相交链表


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. struct ListNode
  4. {
  5.         int val;
  6.         struct ListNode* next;
  7. };
  8. struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
  9. {
  10.         struct ListNode* curA = headA;
  11.         struct ListNode* curB = headB;
  12.         int lenA = 0;
  13.         while (curA->next)
  14.         {
  15.                 ++lenA;
  16.                 curA = curA->next;
  17.         }
  18.        
  19.         int lenB = 0;
  20.         while (curB->next)
  21.         {
  22.                 ++lenB;
  23.                 curB = curB->next;
  24.         }
  25.         //不相交
  26.         if (curA != curB)
  27.         {
  28.                 return NULL;
  29.         }
  30.         int gap = abs(lenA - lenB);
  31.         //因为我们不知道A长还是B长,所以我们要用假设法,先假设A长,如果不对,再调换一下就行
  32.         struct ListNode* longList = headA;
  33.         struct ListNode* shortList = headB;
  34.         if (lenB > lenA)
  35.         {
  36.                 longList = headB;
  37.                 shortList = headA;
  38.         }
  39.         //让长的先走gap步
  40.         while (gap--)
  41.         {
  42.                 longList = longList->next;
  43.         }
  44.         //再同时走,找交点
  45.         while (longList != shortList)
  46.         {
  47.                 longList = longList->next;
  48.                 shortList = shortList->next;
  49.         }
  50.         return longList;
  51. }
复制代码
3. 链表中倒数第k个结点


思路2:
  1. #include <stdio.h>
  2. struct ListNode
  3. {
  4.         int val;
  5.         struct ListNoe* next;
  6. };
  7. struct ListNode* FindKthToTail(struct ListNode* pListHead, int k)
  8. {
  9.         struct ListNode* slow = pListHead, * fast = pListHead;
  10.         //fast先走k步
  11.         while (k--)
  12.         {
  13.                 //k还没有减到0,链表已经空了,说明k大于链表的长度
  14.                 if (NULL == fast)
  15.                 {
  16.                         return NULL;
  17.                 }
  18.                 fast = fast->next;
  19.         }
  20.         //slow和fast同时走,fast走到空,slow就是倒数第k个
  21.         while (fast)
  22.         {
  23.                 slow = slow->next;
  24.                 fast = fast->next;
  25.         }
  26.         return slow;
  27. }
复制代码
4. 环形链表



  1. #include <stdbool.h>
  2. struct ListNode
  3. {
  4.         int val;
  5.         struct ListNode* next;
  6. };
  7. bool hasCycle(struct ListNode* head)
  8. {
  9.         struct ListNode* slow = head, * fast = head;
  10.         while (fast && fast->next)
  11.         {
  12.                 slow = slow->next;
  13.                 fast = fast->next->next;
  14.                 if (slow == fast)
  15.                 {
  16.                         return true;
  17.                 }
  18.         }
  19.         return false;
  20. }
复制代码
5. 环形链表 II

找入环点:

法一:
  1. #include <stdio.h>
  2. struct ListNode
  3. {
  4.         int val;
  5.         struct ListNode* next;
  6. };
  7. struct ListNode* detectCycle(struct ListNode* head)
  8. {
  9.         struct ListNode* slow = head, * fast = head;
  10.         while (fast && fast->next)
  11.         {
  12.                 slow = slow->next;
  13.                 fast = fast->next->next;
  14.                 if (slow == fast)
  15.                 {
  16.                         struct ListNode* meet = slow;
  17.                         while (meet != head)
  18.                         {
  19.                                 meet = meet->next;
  20.                                 head = head->next;
  21.                         }
  22.                         return meet;
  23.                 }
  24.         }
  25.         return NULL;
  26. }
复制代码
法二:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. struct ListNode
  4. {
  5.         int val;
  6.         struct ListNode* next;
  7. };
  8. struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
  9. {
  10.         struct ListNode* curA = headA;
  11.         struct ListNode* curB = headB;
  12.         int lenA = 0;
  13.         while (curA->next)
  14.         {
  15.                 ++lenA;
  16.                 curA = curA->next;
  17.         }
  18.         int lenB = 0;
  19.         while (curB->next)
  20.         {
  21.                 ++lenB;
  22.                 curB = curB->next;
  23.         }
  24.         //不相交
  25.         if (curA != curB)
  26.         {
  27.                 return NULL;
  28.         }
  29.         int gap = abs(lenA - lenB);
  30.         struct ListNode* longList = headA;
  31.         struct ListNode* shortList = headB;
  32.         if (lenB > lenA)
  33.         {
  34.                 longList = headB;
  35.                 shortList = headA;
  36.         }
  37.         //让长的先走gap步
  38.         while (gap--)
  39.         {
  40.                 longList = longList->next;
  41.         }
  42.         //再同时走,找交点
  43.         while (longList != shortList)
  44.         {
  45.                 longList = longList->next;
  46.                 shortList = shortList->next;
  47.         }
  48.         return longList;
  49. }
  50. struct ListNode* detectCycle(struct ListNode* head)
  51. {
  52.         struct ListNode* slow = head, * fast = head;
  53.         while (fast && fast->next)
  54.         {
  55.                 slow = slow->next;
  56.                 fast = fast->next->next;
  57.                 if (slow == fast)
  58.                 {
  59.                         struct ListNode* meet = slow;
  60.                         struct ListNode* headx = meet->next;
  61.                         meet->next = NULL;
  62.                         return getIntersectionNode(head, headx);
  63.                 }
  64.         }
  65.         return NULL;
  66. }
复制代码
6. 随机链表的复制


写代码的时候建议一边画细图,一边写:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. struct Node
  4. {
  5.     int val;
  6.     struct Node *next;
  7.     struct Node *random;
  8. };
  9. struct Node* copyRandomList(struct Node* head)
  10. {
  11.     struct Node* cur = head;
  12.     //拷贝节点插入原节点的后面
  13.     while (cur)
  14.     {
  15.         struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
  16.         copy->val = cur->val;
  17.         //插入
  18.         copy->next = cur->next;
  19.         cur->next = copy;
  20.         //迭代
  21.         cur = cur->next->next;
  22.     }
  23.     //控制拷贝节点的random
  24.     cur = head;
  25.     while (cur)
  26.     {
  27.         struct Node* copy = cur->next;
  28.         
  29.         if (NULL == cur->random)
  30.         {
  31.             copy->random = NULL;
  32.         }
  33.         else
  34.         {
  35.             copy->random = cur->random->next;
  36.         }
  37.         //迭代
  38.         cur = cur->next->next;
  39.     }
  40.     //把copy节点解下来,链接成新链表
  41.     struct Node* copyhead = NULL, * tail = NULL;
  42.     cur = head;
  43.     while (cur)
  44.     {
  45.         struct Node* copy = cur->next;
  46.         struct Node* next = copy->next;
  47.         //尾插
  48.         if (NULL == tail)
  49.         {
  50.             copyhead = tail = copy;
  51.         }
  52.         else
  53.         {
  54.             tail->next = copy;
  55.             tail = tail->next;
  56.         }
  57.         cur->next = next;
  58.         cur = next;
  59.     }
  60.     return copyhead;
  61. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4