两个链表相交问题
1,如果两个单链表相交,输出相交节点
让两个链表先处于同一起跑线,如图所示,然后再 同时向后遍历(从d和h开始同时向后遍历),那么就可以确定是在哪个地方相交的了(确定了在f处相同,即交点)。
那么如何让他俩处于同一起跑线呢?
很简单只需要长的链表先走,走到与短的链表一样长就可以了。
所以解法:
1,分别计算两个链表的长度,得出差值(长的为7,短的为4,差值3)
2,让长的链表先走差值步,此时两个链表长度相同
3,同时遍历两个链表,当相同时,即找到了交点。
我的代码实现参考(思路,可能并不严谨)
//两链表相交问题 class T18{ public static class Node{ private int value; private Node next; public Node(int value){ this.value=value; } } public static Node getNode(Node node1,Node node2){ int node1_len = getLen(node1); //获得两个链表的长度 int node2_len = getLen(node2); Node longLink=node1_len>node2_len?node1:node2; //确定那个是长的 Node shortLink=node1_len<node2_len?node1:node2; int cha=Math.abs(node1_len-node2_len); //得到长度的差值 for (int i = 0; i < cha; i++) { //将长的的起点走到与短的相同 longLink=longLink.next; } while(longLink.value!=shortLink.value){ //知道两个结点相交 longLink=longLink.next; shortLink=shortLink.next; } return longLink; } public static int getLen(Node head){ int length=0; while(head!=null){ head=head.next; length++; } return length; } }
2,一个链表成环问题
解决这个问题的第一步是:如何确定一个链表中包含环。我们可以用两个指针来解决这个问题。和前面的问题一样,定义两个指针,同时从链表的头节点出发,第一个指针一次走一步,第二个指针一次走两步。如果走得快得指针追上了走得慢的指针,那么链表就包含环;如果走得快得指针走到了链表得末尾都没有追上第一个指针,那么链表就不包含环。
第二步是:如何找到环的入口。我们还是可以用两个指针来解决这个问题。先定义两个指针P1和P2指向链表的头节点。如果链表中的环有n个节点,则指针P1先在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向环的入口节点时,第一个指针已经围绕着走了一圈,又回到了入口节点,交汇处便是环的入口节点。
我的代码实现:
//单向链表相交问题:找出环的入口结点 class Find{ public static class Node{ private int value; private Node next; public Node(int value) { this.value = value; } } public Node judge(Node head){ Node n1=head; Node n2=head; while(n1!=null&&n2!=null){ n1=n1.next; n2=n2.next.next; if(n1==n2){ return n1; } } return null; } public Node find(Node head){ int lengh=0; Node judge = judge(head); if(judge==null){ return null; } Node temp1=judge; //得到环中结点的个数 while(judge.next!=temp1){ lengh++; } Node p1=head; for (int i = 0; i <lengh ; i++) { p1=p1.next; } Node p2=head; while(p1!=p2){ p1=p1.next; p2=p2.next; } return p1; } }