链表检测环算法,找到环中的出口节点
- 如何判断一个链表有环
方法是使用快慢指针,通过一个slow指针(每次都指向下一个),一个quick指针(每次都指向下面两个)
因为假设有环的话,quick会追上slow指针
找到环出口就是通过slow指针指向头节点,quick指针指向之前环的交叉点,然后一直以相同速度(慢指针的速度)
遍历直到相遇这样找到的就是出口节点
ps:慢指针遍历速度为每次一个节点,快指针则是遍历两个节点
java实现方法如下
1 2
3 import org.junit.Test;
4
5 public class Main5 {
6 // node
7 private static class node {
8 int val;
9 node next = null;
10
11 public node(int a) {
12 this.val = a;
13 }
14 }
15
16 //
17 public static node create() {
18 // 创建
19 node first = new node(0);
20 node node = first;
21 int i = 1;
22 while (i < 10) {
23 node.next = new node(i);
24 node = node.next;
25 i++;
26 }
27 i = 0;
28 node node2 = first;
29 while (i < 6) {
30 if (i == 5) {
31 node.next = node2;
32 } else {
33 node2 = node2.next;
34 }
35 i++;
36 }
37
38 return first;
39 }
40 //
41 @Test
42 public void test_circle() {
43 node first = create();
44 // 快慢指针方法判断是否为环
45 node quick = first;
46 node slow = first;
47 int i = 0;
48 while (i < 1000) {
49 quick = quick.next.next;
50 slow = slow.next;
51 if (quick == slow) {
52 System.out.println("这个是一个环");
53 break;
54 }
55 i++;
56 }
57 }
58 //
59 //主要是通过快慢指针来判断,慢指针从first节点触发,快指针从交叉点出发,最后的交点就是出口节点
60 @Test
61 public void test_getNode() {
62 node first = create();
63
64 // 快慢指针方法判断是否为环
65 node jiaodian = null;
66 node quick = first;
67 node slow = first;
68 int i = 0;
69 while (i < 1000) {
70 quick = quick.next.next;
71 slow = slow.next;
72 if (quick == slow) {
73 break;
74 }
75 i++;
76 }
77 //
78 slow = first;
79 while(i<1000) {
80 slow = slow.next;
81 quick = quick.next;
82 if(slow == quick) {
83 System.out.println("出口节点"+slow.val);
84 break;
85 }
86 }
87 }
88 }
- 第二个问题就是判断两个链表是否有交点
判断还是很简单的,只要将两个链表遍历到尾节点,如果尾节点相同,这样就证明这两个链表是有交点的
如何找到两个链表相交的节点?
方法:遍历两个链表的长度,然后长链表长度减去短链表长度为K,让长链表减去K,然后两个链表逐个对比
Java代码
1 @Test
2 public void test() {
3 //创建两个链表
4 node first1 = new node(0);
5 node node1 = first1;
6 node first2 = new node(0);
7 node node2 = first2;
8 int i=0;
9 while(i<5) {
10 node1.next = new node(i);
11 i++;
12 }
13 i=0;
14 while(i<5) {
15 node2.next = new node(i);
16 i++;
17 }
18 node ban = new node(6);
19 node node3 = ban;
20 i=0;
21 while(i<5) {
22 node3 = new node(i+5);
23 i++;
24 }
25 node1.next = ban;
26 node2.next = ban;
27 //
28 //这里是判断
29 int length_1 = 0;
30 int length_2 = 0;
31 node1 = first1;
32 node2 = first2;
33 while(node1 != null) {
34 length_1++;
35 node1 = node1.next;
36 }
37 while(node2 != null) {
38 length_2++;
39 node2 = node2.next;
40 }
41
42 int k = 0;
43 if(length_1>=length_2) {
44 k = length_1-length_2;
45 int j = 0;
46 while(j<k) {
47 first1 = first1.next;
48 j++;
49 }
50 }else {
51 k = length_2 - length_1;
52 int j = 0;
53 while(j<k) {
54 first2 = first2.next;
55 j++;
56 }
57 }
58 while(true) {
59 if(first1 == first2) {
60 System.out.println("共同节点"+first1.val);
61 break;
62 }
63 first1 = first1.next;
64 first2 = first2.next;
65 }
66 }