当前位置:   article > 正文

leetcode刷题----单链表oj题

leetcode刷题----单链表oj题

4.链表中倒数第k个节点​编辑

5.合并有序链表

6.链表分割

7.链表的回文

8.链表的环

4.链表中倒数第k个节点3b46648a7db5402ab79add5d50cdd943.png


仿照快慢指针求解中间节点,注意单独处理k>链表表长的情况


  1. struct ListNode* getKthFromEnd(struct ListNode* head, int k)
  2. {
  3. struct ListNode*fast,*slow;
  4. fast=slow=head;
  5. //fast先走k步
  6. while(k--)
  7. {
  8. //表长小于k,则fast为空
  9. if(fast==NULL)
  10. {
  11. return NULL;
  12. }
  13. else
  14. {
  15. fast=fast->next;
  16. }
  17. }
  18. //fast slow一起走
  19. while(fast)
  20. {
  21. fast=fast->next;
  22. slow=slow->next;
  23. }
  24. return slow;
  25. }

5.合并有序链表

题目描述

5b0cc474f7504fe8b19fcdef179e2251.png


方法:归并

从头比较,取小的尾插到新链表,当有一个链表为空时,结束。


4c95843ec9364ef7bfc8297d8b801cac.png

  1. struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
  2. {
  3. if(l1==NULL)
  4. return l2;
  5. if(l2==NULL)
  6. return l1;
  7. struct ListNode*head,*tail;
  8. head=tail=NULL;
  9. while(l1&&l2)
  10. {
  11. if(l1->val<l2->val)
  12. {
  13. if(tail==NULL)
  14. {
  15. head=tail=l1;
  16. }
  17. else
  18. {
  19. tail->next=l1;
  20. tail=tail->next;
  21. }
  22. l1=l1->next;
  23. }
  24. else
  25. {
  26. if(tail==NULL)
  27. {
  28. head=tail=l2;
  29. }
  30. else
  31. {
  32. tail->next=l2;
  33. tail=tail->next;
  34. }
  35. l2=l2->next;
  36. }
  37. }
  38. if(l1)
  39. {
  40. tail->next=l1;
  41. }
  42. if(l2)
  43. {
  44. tail->next=l2;
  45. }
  46. return head;
  47. }

上面这种也可以加一个带哨兵位的头节点,这样就不用判断tail是否为空的情况,开头的那段判断也可以不用

  1. struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
  2. {
  3. struct ListNode*head,*tail;
  4. head=tail=(struct ListNode*)malloc(sizeof( struct ListNode));
  5. tail->next=NULL;
  6. while(l1&&l2)
  7. {
  8. if(l1->val<l2->val)
  9. {
  10. tail->next=l1;
  11. tail=tail->next;
  12. l1=l1->next;
  13. }
  14. else
  15. {
  16. tail->next=l2;
  17. tail=tail->next;
  18. l2=l2->next;
  19. }
  20. }
  21. if(l1)
  22. {
  23. tail->next=l1;
  24. }
  25. if(l2)
  26. {
  27. tail->next=l2;
  28. }
  29. struct ListNode*list=head->next;
  30. free(head);
  31. return list;
  32. }

6.链表分割

题目描述

74ffc9eb533a4234aa4351d0065bd596.png


思路:设置两个带哨兵位的头节点的链表,一个储存比x大的数据,一个储存比x小的数据,最后将两个链表链接起来


7ab118a02712434d9a6c08311656111d.png

  1. /**
  2. * Definition for singly-linked list.
  3. * struct ListNode {
  4. * int val;
  5. * struct ListNode *next;
  6. * };
  7. */
  8. struct ListNode* partition(struct ListNode* head, int x){
  9. //产生两个带哨兵位的头节点
  10. struct ListNode*lesshead,*lesstail,*greaterhead,*greatertail;
  11. lesshead=lesstail=(struct ListNode*)malloc(sizeof(struct ListNode));
  12. lesstail->next=NULL;
  13. greaterhead=greatertail=(struct ListNode*)malloc(sizeof(struct ListNode));
  14. greatertail->next=NULL;
  15. struct ListNode*cur=head;
  16. while(cur)
  17. {
  18. if(cur->val<x)
  19. {
  20. //插入less
  21. lesstail->next=cur;
  22. lesstail=lesstail->next;
  23. }
  24. else
  25. {
  26. //插入greater
  27. greatertail->next=cur;
  28. greatertail=greatertail->next;
  29. }
  30. cur=cur->next;
  31. }
  32. //链接两个链表
  33. lesstail->next=greaterhead->next;
  34. greatertail->next=NULL;//可以避免链表成环问题
  35. struct ListNode*newhead=lesshead->next;
  36. free(greaterhead);
  37. free(lesshead);
  38. return newhead;
  39. }

7.链表的回文

题目描述

78685c6ce52147ca9b1f2ff7323eef29.png


思路:

1.找到中间节点

2.将后半段逆置

3.依次比较


8.相交链表

题目描述947bbbf309ff4734a5f8626b405bec61.png思路:

1.容易发现若两个链表相交,则他们一定有共同的尾节点因为节点的next只能有一个位置

e389c1f67638445e84df37e06486e00e.png

2.主要问题在于保持其原本结构《==》破坏后要恢复


方法

求A的长度lenA,求B的长度lenB.长的A先走差距步,


  1. struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
  2. if(headA==NULL||headB==NULL)
  3. return NULL;
  4. struct ListNode *curA=headA;
  5. struct ListNode *curB=headB;
  6. int lenA=1,lenB=1;
  7. //求表A的长同时找到A的尾节点
  8. while(curA)
  9. {
  10. curA=curA->next;
  11. lenA++;
  12. }
  13. //求表B的长同时找到B的尾节点
  14. while(curB)
  15. {
  16. curB=curB->next;
  17. lenB++;
  18. }
  19. if(curA!=curB)
  20. return NULL;
  21. //求第一个交点
  22. //假设A是短链表,B是长链表
  23. struct ListNode *shortlist=headA;struct ListNode *longlist=headB;
  24. //修正
  25. if(lenA>lenB)
  26. {
  27. longlist=headA;
  28. shortlist=headB;
  29. }
  30. //长的先走gap步
  31. int gap=abs(lenA-lenB);
  32. while(gap--)
  33. {
  34. longlist=longlist->next;
  35. }
  36. //一起后移
  37. while(shortlist!=longlist)
  38. {
  39. longlist=longlist->next;
  40. shortlist=shortlist->next;
  41. }
  42. return shortlist;
  43. }

8.环形链表

思路:类比位移追及问题

62bdb8cb74e34447aa3586d3361c6d92.png

  1. bool hasCycle(struct ListNode *head)
  2. {
  3. struct ListNode *fast,*slow;
  4. fast=slow=head;
  5. while(fast&&fast->next)
  6. {
  7. fast=fast->next->next;
  8. slow=slow->next;
  9. if(fast==slow)
  10. return true;
  11. }
  12. return false;
  13. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/561198
推荐阅读
相关标签
  

闽ICP备14008679号