剑指offer之求两个链表的第一个公共节点

举报
chenyu 发表于 2021/07/27 01:01:04 2021/07/27
【摘要】 1 问题 输入两个链表,找出它们的第一个公共结点。 含有公共节点的两个链表的结构类似于下图中的链表: 1 -> 2 -> 3 -> 4 ->5                2 -> 4 ->5 可以看到两个链表中有一个公共节点,其中4节点就是这两个链...

1 问题

输入两个链表,找出它们的第一个公共结点。

含有公共节点的两个链表的结构类似于下图中的链表:

1 -> 2 -> 3 -> 4 ->5

               2 -> 4 ->5

可以看到两个链表中有一个公共节点,其中4节点就是这两个链表的公共节点  

 

 

 

2 分析

既然题目是求公共节点,说明一定存在这个节点,然后我们可以发现两个链表的尾巴是一样,都重合了是Y性结构,我们先把长的链表的头移动到短的头那里,然后一个接着下一个比较就行

 

 

 

 

3 代码实现


  
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef struct Node
  4. {
  5. int value;
  6. struct Node *next;
  7. } Node;
  8. /*
  9. * 初始化结构体
  10. */
  11. struct Node* init(struct Node *node, int value)
  12. {
  13. node = (struct Node*)malloc(sizeof(Node));
  14. if (node != NULL)
  15. {
  16. node->value = value;
  17. //这个地方不要忘记设置为NULL
  18. node->next = NULL;
  19. return node;
  20. }
  21. return NULL;
  22. }
  23. /*
  24. * 获取链表的长度
  25. */
  26. int length(Node *head)
  27. {
  28. if (head == NULL)
  29. return 0;
  30. Node *p = head;
  31. int length = 0;
  32. while (p != NULL)
  33. {
  34. length++;
  35. p = p->next;
  36. }
  37. return length;
  38. }
  39. /**
  40. * 找到第一个公共的节点
  41. */
  42. struct Node* get_common(Node *head1, Node *head2)
  43. {
  44. if (head1 == NULL || head2 == NULL)
  45. {
  46. return NULL;
  47. }
  48. int list1_length = length(head1);
  49. int list2_length = length(head2);
  50. Node *short_head = NULL;
  51. Node *long_head = NULL;
  52. int sub_len = 0;
  53. if (list1_length > list2_length)
  54. {
  55. short_head = head2;
  56. long_head = head1;
  57. sub_len = list1_length - list2_length;
  58. }
  59. else
  60. {
  61. short_head = head1;
  62. long_head = head2;
  63. sub_len = list2_length - list1_length;
  64. }
  65. //移动长链表,确保两个链表一样长
  66. while (sub_len > 0)
  67. {
  68. sub_len--;
  69. long_head = long_head->next;
  70. }
  71. while (short_head != NULL && long_head != NULL)
  72. {
  73. if (short_head->value == long_head->value)
  74. {
  75. return short_head;
  76. }
  77. short_head = short_head->next;
  78. long_head = long_head->next;
  79. }
  80. return NULL;
  81. }
  82. int main()
  83. {
  84. Node *n1 = NULL;
  85. Node *n2 = NULL;
  86. Node *n3 = NULL;
  87. Node *n4 = NULL;
  88. Node *n5 = NULL;
  89. Node *m1 = NULL;
  90. Node *m2 = NULL;
  91. Node *m3 = NULL;
  92. n1 = init(n1, 1);
  93. n2 = init(n2, 2);
  94. n3 = init(n3, 3);
  95. n4 = init(n4, 4);
  96. n5 = init(n5, 5);
  97. m1 = init(m1, 2);
  98. m2 = init(m2, 4);
  99. m3 = init(m3, 5);
  100. if (n1 && n2 && n3 && n4 && n5)
  101. {
  102. n1->next = n2;
  103. n2->next = n3;
  104. n3->next = n4;
  105. n4->next = n5;
  106. }
  107. if (m1 && m2 && m3)
  108. {
  109. m1->next = m2;
  110. m2->next = m3;
  111. }
  112. Node *node = get_common(n1, m2);
  113. if (node)
  114. {
  115. printf("common node value is: %d\n", node->value);
  116. }
  117. else
  118. {
  119. printf("two list do not common value\n");
  120. }
  121. if (n1) {free(n1); n1 = NULL;}
  122. if (n2) {free(n2); n2 = NULL;}
  123. if (n3) {free(n3); n3 = NULL;}
  124. if (n4) {free(n4); n4 = NULL;}
  125. if (n5) {free(n5); n5 = NULL;}
  126. if (m1) {free(m1); m1 = NULL;}
  127. if (m2) {free(m2); m1 = NULL;}
  128. if (m3) {free(m3); m1 = NULL;}
  129. return 1;
  130. }

 

 

 

4 运行结果

common node value is: 4
 

 

 

 

 

5 总结

如果我们求链表的长度,一般是这样的函数


  
  1. /*
  2. * 获取链表的长度
  3. */
  4. int length(Node *head)
  5. {
  6. if (head == NULL)
  7. return 0;
  8. Node *p = head;
  9. int length = 0;
  10. while (p != NULL)
  11. {
  12. length++;
  13. p = p->next;
  14. }
  15. return length;
  16. }

一定要记到骨髓里面去。

文章来源: chenyu.blog.csdn.net,作者:chen.yu,版权归原作者所有,如需转载,请联系作者。

原文链接:chenyu.blog.csdn.net/article/details/86501502

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。