zoukankan      html  css  js  c++  java
  • 两个单链表相交的问题

    单链表可能有环无环;

    给定两个 单链表的头节点 head1和head2,这两个链表可能相交,也可能 不相交。请实现一个函数, 如果两个链表相交,请返回相交的 第一个节点;如果不相交,返回null 即可。

    链表长度分别为 N M, 时间复杂度O(N + M);额外空间 O(1) ;

      1 package my_basic.class_3;
      2 
      3 public class FindFirstIntersectNode {
      4     public static class Node{
      5         int value;
      6         Node next;
      7         public Node(int data) {
      8             this.value = data;
      9         }
     10     }
     11     /**
     12      * 找到相交节点
     13      * @return
     14      */
     15     public static Node getIntersectNode(Node head1,Node head2) {
     16         if (head1 == null || head2==null) {
     17             return null;
     18         }
     19         //环节点
     20         Node loop1 = getLoopNode(head1);
     21         Node loop2 = getLoopNode(head2);
     22         
     23         if (loop1 == null && loop2 == null) {
     24             return getNoLoop(head1,head2);
     25         }
     26         if (loop1!=null && loop2!=null) {
     27             return bothLoop(head1,loop1,head2,loop2);
     28         }
     29         return null;
     30         
     31     }
     32     
     33     //判断有没有环 如果有环 返回第一个入环节点
     34     //第1种:hashset实现 
     35     //第2种:一个快指针 一个慢指针 ; 如果相遇了, 快指针从头开始 每次一步走,首次相遇的节点就是第一个入环节点
     36     public static Node getLoopNode(Node head) {
     37         //2. 
     38         if (head == null || head.next == null || head.next.next == null ) {
     39             return null;
     40         }
     41         Node n1;  //slow
     42         Node n2;  //fast
     43         n1 = head.next;
     44         n2 = head.next.next;
     45         while(n1 != n2) {
     46             if (n2.next == null || n2.next.next == null ) {
     47                 return null;
     48             }
     49             n1 = n1.next;
     50             n2 = n2.next.next;
     51         }
     52         n2 = head;
     53         while (n1 != n2) {
     54             n1 = n1.next;
     55             n2 = n2.next;
     56         }
     57         return n1;
     58         
     59         //1. 需要额外的哈希表做辅助空间
     60         /*HashSet<Object> set = new HashSet<>();
     61         Node n1 = head;  
     62         while (n1 != null) {
     63             if (set.contains(n1)) {
     64                 return n1;
     65             }
     66             set.add(n1);
     67             n1 = n1.next;
     68         }
     69         return null;*/
     70     }
     71     
     72     //都没有环: 也可以借助hashset
     73     public static Node getNoLoop(Node head1, Node head2) {
     74         if (head1==null || head2 == null) {
     75             return null;
     76         }
     77         Node cur1 = head1;  //long list
     78         Node cur2 = head2;  //short  list
     79         int n=0;
     80         while (cur1.next != null) {
     81             n++;
     82             cur1 = cur1.next;
     83         }
     84         while (cur2.next != null) {
     85             n--;
     86             cur2 = cur2.next;
     87         }
     88         if (cur1 != cur2) {
     89             return null;
     90         } 
     91         cur1 = n>0 ? head1 : head2;
     92         cur2 = cur1 == head1 ? head2 : head1;
     93         
     94         n = Math.abs(n);
     95         while (n != 0) {
     96             n--;
     97             cur1 = cur1.next;
     98         }
     99         while (cur1 != cur2) {
    100             cur1 = cur1.next;
    101             cur2 = cur2.next;
    102         }
    103         return cur1;
    104     }
    105     
    106     //都有环: 也可以借助hashset
    107     public static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) {
    108         if (loop1 == loop2 ) {
    109             Node cur1 = head1;  //long
    110             Node cur2 = head2;  //short
    111             int n=0;
    112             while (cur1.next != loop1) {
    113                 n++;
    114                 cur1 = cur1.next;
    115             }
    116             while (cur2.next != loop2) {
    117                 n--;
    118                 cur2 = cur2.next;
    119             }
    120             if (cur1 != cur2) {
    121                 return null;
    122             } 
    123             cur1 = n>0 ? head1 : head2;
    124             cur2 = cur1 == head1 ? head2 : head1;
    125             
    126             n = Math.abs(n);
    127             while (n > 0) {
    128                 n--;
    129                 cur1 = cur1.next;
    130             }
    131             while (cur1 != cur2) {
    132                 cur1 = cur1.next;
    133                 cur2 = cur2.next;
    134             }
    135             return cur1;
    136         }else{
    137             Node n = loop1.next;
    138             while(n != loop1) {
    139                 if (n == loop2) {
    140                     return loop1;
    141                 }
    142                 n = n.next;
    143             }
    144             return null;
    145         }
    146     }
    147     
    148     public static void main(String[] args) {
    149         // 1->2->3->4->5->6->7->null
    150         Node head1 = new Node(1);
    151 //        head1.next = new Node(2);
    152 //        head1.next.next = new Node(3);
    153 //        head1.next.next.next = new Node(4);
    154 //        head1.next.next.next.next = new Node(5);
    155 //        head1.next.next.next.next.next = new Node(6);
    156 //        head1.next.next.next.next.next.next = new Node(7);
    157 //
    158 //        // 0->9->8->6->7->null
    159         Node head2 = new Node(0);
    160 //        head2.next = new Node(9);
    161 //        head2.next.next = new Node(8);
    162 //        head2.next.next.next = head1.next.next.next.next.next; // 8->6
    163 //        System.out.println(getIntersectNode(head1, head2).value);
    164 //
    165         // 1->2->3->4->5->6->7->4...
    166         head1 = new Node(1);
    167         head1.next = new Node(2);
    168         head1.next.next = new Node(3);
    169         head1.next.next.next = new Node(4);
    170         head1.next.next.next.next = new Node(5);
    171         head1.next.next.next.next.next = new Node(6);
    172         head1.next.next.next.next.next.next = new Node(7);
    173         head1.next.next.next.next.next.next.next = head1.next.next.next; // 7->4
    174 
    175 //        // 0->9->8->2...
    176 //        head2 = new Node(0);
    177 //        head2.next = new Node(9);
    178 //        head2.next.next = new Node(8);
    179 //        head2.next.next.next = head1.next; // 8->2
    180 //        System.out.println(getIntersectNode(head1, head2).value);
    181 
    182         // 0->9->8->6->4->5->6..
    183         head2 = new Node(0);
    184         head2.next = new Node(9);
    185         head2.next.next = new Node(8);
    186         head2.next.next.next = head1.next.next.next.next.next; // 8->6
    187         System.out.println(getIntersectNode(head1, head2).value);
    188 
    189     }
    190 }
  • 相关阅读:
    小黄衫获奖感言
    原型设计
    20210326编程作业
    阅读任务
    准备工作
    cmd命令行批量修改文件名后缀
    【智能算法】模拟退火算法
    【智能算法】粒子群寻优算法
    【并行计算】基于OpenMP的并行编程
    Python科学计算——前期准备
  • 原文地址:https://www.cnblogs.com/lihuazhu/p/10782583.html
Copyright © 2011-2022 走看看