zoukankan      html  css  js  c++  java
  • 链表检测环算法,找到环中的出口节点

    • 如何判断一个链表有环

      方法是使用快慢指针,通过一个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     }

      

        

  • 相关阅读:
    .NET Cache缓存
    异步
    es6常用功能
    vue-router路由懒加载
    vue中nextTick和$nextTick
    动态模板中 swiper 划不动问题
    javaScript正则判断手机号
    Mac终端使用技巧
    alert IOS自带域名
    vue css background路径不对
  • 原文地址:https://www.cnblogs.com/feizhai/p/9653264.html
Copyright © 2011-2022 走看看