• 快慢指针的应用


    1.判断单链表是否存在环

     1 * Definition for singly-linked list.
     2  * public class ListNode {
     3  *     public int val;
     4  *     public ListNode next;
     5  *     public ListNode(int x) {
     6  *         val = x;
     7  *         next = null;
     8  *     }
     9  * }
    10  */
    11 public class Solution {
    12     public bool HasCycle(ListNode head) {
    13          if(head == null){
    14             return false;
    15         }
    16         ListNode slow = head;
    17         ListNode fast = head;
    18         while (fast !=null && fast.next!=null){
    19             slow = slow.next;
    20             fast = fast.next.next;
    21             if(slow == fast){
    22                 return true;
    23             }
    24         }
    25         return false;
    26     }
    27 }

     如果链表存在环,就好像操场的跑道是一个环形一样。此时让快慢指针都从链表头开始遍历,快指针每次向前移动两个位置,慢指针每次向前移动一个位置;如果快指针到达NULL,说明链表以NULL为结尾,没有环。如果快指针追上慢指针,则表示有环.

    2.判断两个单链表是否相交,如果相交,找到他们的第一个公共节点

    编写一个程序,找到两个单链表相交的起始节点。

    如下面的两个链表:

    在节点 c1 开始相交。

    示例 1:

    输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
    输出:Reference of the node with value = 8
    输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
    

    示例 2:

    输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
    输出:Reference of the node with value = 2
    输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
    

    示例 3:

    输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
    输出:null
    输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
    解释:这两个链表不相交,因此返回 null。

    这道题有三种解决方法
    (1)利用快慢指针将链表1的尾结点的next赋给链表2的头结点,在循环过程中如果slow==fast则证明存在环,之后再创建一组快慢指针找到相的结点
     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     public int val;
     5  *     public ListNode next;
     6  *     public ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode GetIntersectionNode(ListNode headA, ListNode headB) {
    11         if(headA==null||headB==null)
    12             return null;
    13         ListNode tmp=headB;
    14         while(tmp.next!=null)
    15         {
    16             tmp=tmp.next;
    17         }
    18         tmp.next=headB;
    19         ListNode slow=headA;
    20         ListNode fast=headA;
    21         while(fast!=null&&fast.next!=null)
    22         {
    23             slow=slow.next;
    24             fast=fast.next.next;
    25             if(fast==slow)
    26             {
    27                 slow=headA;
    28                 while(slow!=fast)
    29                 {
    30                     slow=slow.next;
    31                     fast=fast.next;
    32                 }
    33                 tmp.next=null;
    34                 return fast;
    35             }
    36         }
    37         tmp.next=null;
    38         return null;
    39     }
    40 }
    (2)两链表相连
     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     public int val;
     5  *     public ListNode next;
     6  *     public ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode GetIntersectionNode(ListNode headA, ListNode headB) {
    11         if(headA == null || headB == null) return null;
    12         ListNode pA = headA, pB = headB;
    13         // 在这里第一轮体现在pA和pB第一次到达尾部会移向另一链表的表头, 而第二轮体现在如果pA或pB相交就返回交点, 不相交最后就是null==null
    14         while(pA != pB) {
    15             pA = pA == null ? headB : pA.next;
    16             pB = pB == null ? headA : pB.next;
    17         }
    18         return pA;
    19     }
    20 }
    View Code
     (3)使两个链表长度相等,循环依次比较

    3.用快慢指针获取中间结点
     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     public int val;
     5  *     public ListNode next;
     6  *     public ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public ListNode MiddleNode(ListNode head) {
    11         ListNode slow=head;
    12         ListNode fast=head;
    13         if(head!=null)
    14         {
    15         while(fast!=null&&fast.next!=null)
    16             {
    17                 slow=slow.next;
    18                 fast=fast.next.next;
    19             }
    20         }
    21         
    22         return slow;
    23     }
    24 }
    View Code
    
    

    通过找到中间结点的方法,也可以借此判断该链表是否是回文

     
     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     public int val;
     5  *     public ListNode next;
     6  *     public ListNode(int x) { val = x; }
     7  * }
     8  */
     9 public class Solution {
    10     public bool IsPalindrome(ListNode head) {
    11         ListNode slow = head;
    12             ListNode fast = head;
    13             ListNode temp = head;
    14             while(fast!=null&&fast.next!=null)
    15             {
    16                 slow = slow.next;
    17                 fast = fast.next.next;
    18             }
    19             slow = ReverseList(slow);
    20             while(slow!=null)
    21             {
    22                 if (temp.val != slow.val)
    23                     return false;
    24                 else
    25                 {
    26                     temp = temp.next;
    27                     slow = slow.next;
    28                 }
    29             }
    30             return true;
    31     }
    32     public ListNode ReverseList(ListNode head) {
    33         ListNode prev = null; 
    34         ListNode curr = head; 
    35         while (curr != null) {
    36             ListNode nextTemp = curr.next; 
    37             curr.next = prev; 
    38             prev = curr;
    39             curr = nextTemp;
    40         }
    41         return prev;
    42     }
    43 }
    View Code
    
    
    
    
    
    
    
    
  • 相关阅读:
    青城的另一个一夜/情
    SystemProperties.get/set property_get/set
    锁——Java同步的基本思想
    CMUSphinx Learn
    猜数字
    我的音乐我的电影
    动态规划_钢条切割问题
    directdraw显示yuv420(YV12)
    Redis 命令参考
    HDU 3078 LCA转RMQ
  • 原文地址:https://www.cnblogs.com/gsh520/p/10926118.html
Copyright © 2020-2023  润新知