剑指offer系列62---两个链表的公共结点

【题目】输入两个链表,找出它们的第一个公共结点。
* 【思路】1 获取两链表的长度;
* 2 让长的链表先走n步后此时走到短链表起始位置;
* 3 两链表同时遍历,直至相同,这时返回第一个公共结点。

 1 package com.exe11.offer;
 2
 3 /**
 4  * 【题目】输入两个链表,找出它们的第一个公共结点。
 5  * 【思路】1 获取两链表的长度;
 6  *           2 让长的链表先走n步后此时走到短链表起始位置;
 7  *           3 两链表同时遍历,直至相同,这时返回第一个公共结点。
 8  * @author WGS
 9  *
10  */
11 public class CommonListNode {
12
13     static class ListNode{
14         int val;
15         ListNode next=null;
16         public ListNode(int val){
17             this.val=val;
18         }
19     }
20     public ListNode getCommonNode(ListNode pHead1,ListNode pHead2){
21         if(pHead1==null ||pHead2==null)
22             return null;
23         //1 获取两个链表长度
24         int len1=getListNodeLength(pHead1);
25         int len2=getListNodeLength(pHead2);
26         //2 比较长度
27         int difVal=len1-len2;
28         ListNode longListNode=pHead1;
29         ListNode shortListNode=pHead2;//假设pHead1长,pHead2短
30         if(difVal<0){//len1<len2,pHead2长
31             longListNode=pHead2;
32             shortListNode=pHead1;
33             difVal=len2-len1;
34         }
35         //3 让长的先走n(difVal)步
36         for(int i=0;i<difVal;i++){
37             longListNode=longListNode.next;
38         }
39         //4 再一起走
40         while(longListNode!=null && shortListNode!=null &&(longListNode.val!=shortListNode.val)){
41             longListNode=longListNode.next;
42             shortListNode=shortListNode.next;
43         }
44         //当碰到相同值即为公共结点,跳出循环
45         ListNode commonNode=longListNode;
46         /*if(longListNode.val==shortListNode.val){
47             commonNode=shortListNode;//返回 公共结点
48         }*/
49
50         return commonNode;
51
52     }
53     //获取链表长度
54     private int getListNodeLength(ListNode pHead){
55         ListNode node=pHead;
56         int len=0;
57         while(node!=null){
58             len++;
59             node=node.next;
60         }
61         return len;
62     }
63
64
65
66
67
68
69     public static void main(String[] args) {
70           ListNode pHead1 = new ListNode(1);
71             ListNode node1 = new ListNode(2);
72             ListNode node2 = new ListNode(3);
73             ListNode node3 = new ListNode(4);
74            // ListNode node4 = new ListNode(7);
75             pHead1.next = node1;
76             node1.next = node2;
77             node2.next = node3;
78             //node3.next = node4;
79
80             ListNode pHead2 = new ListNode(5);
81             ListNode node5 = new ListNode(6);
82             ListNode node6 = new ListNode(7);
83            // ListNode node7 = new ListNode(7);
84             pHead2.next = node5;
85             node5.next = node6;
86            // node6.next = node7;
87
88             CommonListNode c=new CommonListNode();
89             ListNode node=c.getCommonNode(pHead1, pHead2);
90             System.out.println(node);
91
92     }
93
94 }

或者,用一个集合先把第一个链表所有值加入,再依次跟第二个链表值比较,当有第一个相同时即为第一个公共结点。

 1 package com.exe11.offer;
 2
 3 import java.util.HashMap;
 4
 5 /**
 6  * 【题目】输入两个链表,找出它们的第一个公共结点。
 7  * 【思路】1 获取两链表的长度;
 8  *           2 让长的链表先走n步后此时走到短链表起始位置;
 9  *           3 两链表同时遍历,直至相同,这时返回第一个公共结点。
10  * @author WGS
11  *
12  */
13 public class CommonListNode2 {
14
15     static class ListNode{
16         int val;
17         ListNode next=null;
18         public ListNode(int val){
19             this.val=val;
20         }
21     }
22     public ListNode getCommonNode(ListNode pHead1,ListNode pHead2){
23         HashMap<ListNode,Integer> map=new HashMap<>();
24         //先把pHead1值全部添加至集合中
25         while(pHead1!=null){
26             map.put(pHead1, 1);
27             pHead1=pHead1.next;
28         }
29         //
30         //ListNode commonNode=null;
31         while(pHead2!=null){
32             Integer node=map.get(pHead2);
33             if(node!=null)
34                 return pHead2;
35             pHead2=pHead2.next;
36         }
37         return null;
38
39     }
40
41
42
43
44     public static void main(String[] args) {
45           ListNode pHead1 = new ListNode(1);
46             ListNode node1 = new ListNode(2);
47             ListNode node2 = new ListNode(3);
48             ListNode node3 = new ListNode(4);
49            // ListNode node4 = new ListNode(7);
50             pHead1.next = node1;
51             node1.next = node2;
52             node2.next = node3;
53             //node3.next = node4;
54
55             ListNode pHead2 = new ListNode(5);
56             ListNode node5 = new ListNode(6);
57             ListNode node6 = new ListNode(7);
58            // ListNode node7 = new ListNode(7);
59             pHead2.next = node5;
60             node5.next = node6;
61            // node6.next = node7;
62
63             CommonListNode2 c=new CommonListNode2();
64             ListNode node=c.getCommonNode(pHead1, pHead2);
65             System.out.println(node.val);
66
67     }
68
69 }
时间: 2024-12-24 23:24:17

剑指offer系列62---两个链表的公共结点的相关文章

剑指offer系列——36.两个链表的第一个公共结点

Q:输入两个链表,找出它们的第一个公共结点.(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的) T:这个题的意思是两个链表要么有公共结点,要么没有公共结点,不存在相交的情况. A: 1.传统做法:长的先走,直到和短的相同长度,然后两个一起走,直至相等. ListNode *FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2) { if (pHead1 == nullptr || pHead2 ==

剑指offer七:两个链表的第一个公共结点

输入两个链表,找出它们的第一个公共结点. import java.util.*; public class Solution { public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { ListNode current1 = pHead1; ListNode current2 = pHead2; HashMap<ListNode,Integer> hashMap = new HashMap<ListN

剑指offer系列9:反转链表

两个思路: 1.将传来的链表结点一个一个反转,需要使用3个指针,分别指向前结点.当前结点.后结点. 2.从表头开始遍历,每遍历一个结点,将该结点存入一个新链表的头结点. 先说第一个,这个我做的时候有点绕,认真的把结点的指针图画出来理清楚了思路.注释把思路解释的很清楚了,代码如下: 1 #include<iostream> 2 using namespace std; 3 struct ListNode { 4 int val; 5 struct ListNode *next; 6 ListNo

剑指offer系列源码-反转链表

题目1518:反转链表 时间限制:1 秒内存限制:128 兆特殊判题:否提交:1952解决:741 题目描述: 输入一个链表,反转链表后,输出链表的所有元素. (hint : 请务必使用链表) 输入: 输入可能包含多个测试样例,输入以EOF结束. 对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000):代表将要输入的链表的个数. 输入的第二行包含n个整数t(0<=t<=1000000):代表链表元素. 输出: 对应每个测试案例, 以此输出链表反转后的元素,如没有元素则输

剑指offer系列-用两个栈实现队列

oj地址 题目1512:用两个栈实现队列 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:2360 解决:804 题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 输入: 每个输入文件包含一个测试样例. 对于每个测试样例,第一行输入一个n(1<=n<=100000),代表队列操作的个数. 接下来的n行,每行输入一个队列操作: 1. PUSH X 向队列中push一个整数x(x>=0) 2. POP 从队列中pop一个数. 输出:

剑指offer系列12---链表倒数第k个结点

[题目]输入一个链表,输出该链表中倒数第k个结点. [思路]方法3:设置两个指针,第一个指针先走k-1步,第2个指针开始走,(这时候第一个指针指向第k个)当第一个指针走到尾部时(即走了k步),第一个指针即指向第k个结点.(推荐的方法) 方法2:先获取结点个数,再顺数第n-k+1个结点 1 2 3 4 5 6 方法1:先获取长度,再复制至数组一中,再反序加至数组2中,这时候要输出倒数第K个数即为数组2中的顺数第k-1个数.此处出现的异常不知道该怎么处理.(我的方法) 1 package com.e

剑指Offer:合并两个排序的链表【25】

剑指Offer:合并两个排序的链表[25] 题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 题目分析 每次都是比较箭头节点,把小节点连接到已经合并的链表之后,重复的执行此过程,最后如果那个链表已经走完,那就将另一个链表直接连接到合并的链表之后. Java题解 public static ListNode Merge(ListNode list1,ListNode list2) { if(list1==null) return list2;

剑指Offer系列之题11~题15

目录 11.矩形覆盖 12.二进制中1的个数 13. 数值的整数次方 14.调整数组顺序使奇数位于偶数前面 15.链表中倒数第k个结点 11.矩形覆盖 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 比如n=3时,2*3的矩形块有3种覆盖方法: 斐波那契数列的应用 第一次竖着放一块类比为走一步,第一次横着放两块类比为走两步 代码与上面的斐波那契数列类题目类似,此处不再赘述:剑指Offer系列之题6~题10. 12.

剑指OFFER之用两个栈实现队列(九度OJ1512)

题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 输入: 每个输入文件包含一个测试样例.对于每个测试样例,第一行输入一个n(1<=n<=100000),代表队列操作的个数.接下来的n行,每行输入一个队列操作:1. PUSH X 向队列中push一个整数x(x>=0)2. POP 从队列中pop一个数. 输出: 对应每个测试案例,打印所有pop操作中从队列pop中的数字.如果执行pop操作时,队列为空,则打印-1 样例输入: 3 PUSH 10

【剑指offer】Q16:翻转链表

def reverse(head): if head == None or head.next == None: return head psuhead = ListNode(-1) while head: nexthead = head.next head.next = psuhead.next psuhead.next = head head = nexthead head = psuhead.next del psuhead return head [剑指offer]Q16:翻转链表