• LeetCode ——160. 相交链表,142. 环形链表 II


    ✅<1>主页:C语言的前男友
    📃<2>知识讲解:LeetCode经典链表笔试题目
    🔥<3>创作者:C语言的前男友
    ☂️<4>开发环境:Visual Studio 2022
    🏡<5>系统环境:Windows 10
    💬<6>前言:今天来讲解几个经典的链表题目,链接已经给出大家可以挑战一下。

    目录

    160. 相交链表

    题目链接:160. 相交链表

    题目描述:

     思路一:

    代码:

    思路二:

    代码:

    142. 环形链表 II

    题目链接:142. 环形链表 II

    题目描述:

    思路一:

     代码:

    思路二:

    代码:

     最后:成为自己想成为的样子,才能得到自己想得到的东西。


    160. 相交链表

    题目链接:160. 相交链表

    题目描述:

    给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。图示两个链表在节点 c1 开始相交

     思路一:

    如果两个链表相交,则必有公共结点,我们只需要返回第一个公共结点就可以了,第一个公共结点就是第一个相交结点。怎么找他的第一个公共结点呢?最简单的就是两个循环,去遍历两个链表。用链表B中的结点挨个与链表A的结点比较是否相等。如果存在相等的结点,第一个相等的结点就是两个单链表相交的起始节点,返回任意一个结点。如果没有相交结点,那么两个链表不相交,返回 NULL 。此方法时间复杂度为O(n^2).

    代码:

    1. struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
    2. {
    3. for(struct ListNode*i=headA;i!=NULL;i=i->next)
    4. {
    5. for(struct ListNode*j=headB;j!=NULL;j=j->next)
    6. {
    7. if(i==j)
    8. {
    9. return i;
    10. }
    11. }
    12. }
    13. return NULL;
    14. }

    思路二:

    如果让两个指针能从下面的地方开始走,那么两个指针相遇的时候一定就是两个单链表相交的起始节点。

     那么问题就是怎么找到这两个位置。其实不难发现只要让 curB 先走,让 curB 之后的链表节点数与 curA 后面的节点数一样。只要让长的链表先走 长链表比短链表多的节点数的 步数,就可以了。

    代码:

    1. struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    2. struct ListNode*listA=headA;
    3. struct ListNode*listB=headB;
    4. int countA=0; //A链表的长度
    5. int countB=0; //B链表的长度
    6. //计算B链表的长度
    7. while(listA)
    8. {
    9. countA++;
    10. listA=listA->next;
    11. }
    12. //计算A链表的长度
    13. while(listB)
    14. {
    15. countB++;
    16. listB=listB->next;
    17. }
    18. //计算长度差
    19. int n=abs(countA-countB);
    20. //先假设A为长链表,B为短炼表
    21. struct ListNode*longlist=headA;
    22. struct ListNode*shortlist=headB;
    23. //如果不符合就纠正一下
    24. if(countB>countA)
    25. {
    26. longlist=headB;
    27. shortlist=headA;
    28. }
    29. //让长链表先走
    30. while(n--)
    31. {
    32. longlist=longlist->next;
    33. }
    34. //长短链表同时走
    35. while(longlist&&shortlist)
    36. {
    37. //第一次相遇就是相交的第一个结点
    38. if(longlist==shortlist)
    39. {
    40. return longlist;
    41. }
    42. longlist=longlist->next;
    43. shortlist=shortlist->next;
    44. }
    45. return NULL;
    46. }

    142. 环形链表 II

    题目链接:142. 环形链表 II

    题目描述:

    给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos-1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。不允许修改 链表。

     

    思路一:

    利用带环链表的特点加上严格的逻辑推导:

     代码:

    1. struct ListNode *detectCycle(struct ListNode *head){
    2. struct ListNode*frist=head;//快指针
    3. struct ListNode*slow=head;//慢指针
    4. //如果遇到结点为空,就说明不是带环结点,直接返回NULL
    5. while(frist&&frist->next)
    6. {
    7. frist=frist->next->next; //快指针一次走两步
    8. slow=slow->next; //慢指针一次走一步
    9. if(frist==slow)//在环中相遇
    10. {
    11. struct ListNode*meet=frist;//一个从环中走
    12. struct ListNode*cur=head;//一个从链表头走
    13. while(meet!=cur)//相遇是循环结束
    14. {
    15. meet=meet->next;
    16. cur=cur->next;
    17. }
    18. return meet;//相遇的结点就是环入口点
    19. }
    20. }
    21. return NULL;
    22. }

    思路二:

    利用快慢指针,让两指针在环中相遇点,将相遇点拆开。相遇点的后一个结点变成新的头节点,相遇点的next指向NULL。这样带环问题就变成了,两个链表相交的问题。

    产生的两条新的链表,head 和 phead  ,两条链表相交的第一个的以公共结点就是,以前带环链表的环入口处。

    代码:

    1. //找到链表相交的第一个结点
    2. struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    3. struct ListNode*listA=headA;
    4. struct ListNode*listB=headB;
    5. int countA=0;
    6. int countB=0;
    7. while(listA)
    8. {
    9. countA++;
    10. listA=listA->next;
    11. }
    12. while(listB)
    13. {
    14. countB++;
    15. listB=listB->next;
    16. }
    17. int n=abs(countA-countB);
    18. struct ListNode*longlist=headA;
    19. struct ListNode*shortlist=headB;
    20. if(countB>countA)
    21. {
    22. longlist=headB;
    23. shortlist=headA;
    24. }
    25. while(n--)
    26. {
    27. longlist=longlist->next;
    28. }
    29. while(longlist&&shortlist)
    30. {
    31. if(longlist==shortlist)
    32. {
    33. return longlist;
    34. }
    35. longlist=longlist->next;
    36. shortlist=shortlist->next;
    37. }
    38. return NULL;
    39. }
    40. struct ListNode *detectCycle(struct ListNode *head)
    41. {
    42. struct ListNode*frist=head;
    43. struct ListNode*slow=head;
    44. while(frist&&frist->next)
    45. {
    46. frist=frist->next->next;
    47. slow=slow->next;
    48. //快慢指针在环中相遇
    49. if(frist==slow)
    50. {
    51. //拆分环行链表段
    52. struct ListNode*phead=frist->next;
    53. slow->next=NULL;
    54. //返回相交结点
    55. return getIntersectionNode(phead,head);
    56. }
    57. }
    58. return NULL;
    59. }

     最后:成为自己想成为的样子,才能得到自己想得到的东西。

     

     

     

     

     

     

     

  • 相关阅读:
    QSS样式表的使用
    Docker本地部署开源浏览器Firefox并远程访问进行测试
    Linux上编译sqlite3库出现undefined reference to `sqlite3_column_table_name‘
    强固型国产化工业电脑,在电子看板行业应用,机器视觉在汽车产线行业应用
    AI绘制流程图
    axios升级依赖版本后报错SyntaxError: Cannot use import statement outside a module
    【优选算法系列】第一节.双指针(283. 移动零和1089. 复写零)
    氨基苯酚/多巴胺仿生修饰碳纳米管/α-氧化铝/ CNTs-Ag纳米复合材料
    小程序自定义导航栏
    Python接口自动化 —— Json 数据处理实战(详解)
  • 原文地址:https://blog.csdn.net/qq_63943454/article/details/127752077