链表检测环算法,找到环中的出口节点
- 如何判断一个链表有环
方法是使用快慢指针,通过一个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 }