快慢指针算法与应用

基本概念

快慢指针中的快慢指的是移动的步长,即每次向前移动速度的快慢。例如可以让快指针每次沿链表向前移动2,慢指针每次向前移动1次。

应用

1.判断单链表是否为循环链表(Leetcode-141)
让快慢指针从链表头开始遍历,快指针向前移动两个位置,慢指针向前移动一个位置;如果快指针到达NULL,说明链表以NULL为结尾,不是循环链表。如果 快指针追上慢指针,则表示出现了循环。

public class Solution {
    public boolean hasCycle(ListNode head) {
        
        ListNode first = head;
        ListNode second = head;
        
        while(second!=null && second.next != null){
            first = first.next;
            second = second.next.next;
            if(first == second){
                return true;
            }
        }
        return false;
    }
}

2.在有序链表中寻找中位数(Leetcode-876)
该方法在不借助计数器变量实现寻找中位数的功能。原理是:快指针的移动速度是慢指针移动速度的2倍,因此当快指针到达链表尾时,慢指针到达中点。程序还要考虑链表结点个数的奇偶数因素,当快指针移动x次后到达表尾(1+2x),说明链表有奇数个结点,直接返回慢指针指向的数据即可。如果快指针是倒数第二个结点,说明链表结点个数是偶数,这时可以根据“规则”返回上中位数或下中位数或(上中位数+下中位数)的一半。

class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode slow  = head;
        ListNode fast = head;
        while(slow!=null&&fast!=null&&fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }
}

3.两个单链表相交的起始节点(Leetcode-160)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    
    /**
     * 链表向交,尾节点相等
     *   A:          a1 → a2
     *                      ↘
     *                        c1 → c2 → [c3]相等节点
     *                      ↗            
     *   B:     b1 → b2 → b3
     *
     * 相交的位置为 :
     * diff = 长链表长度-短链表长度 ,长链表先走diff长度,之后一起走,判断节点是否相等
     */
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA == null || headB == null){
            return null;
        }
            
        ListNode iteratorA = headA;
        ListNode iteratorB = headB;
        int lenA = 0;
        int lenB = 0;
        while(iteratorA!=null||iteratorB!=null){
            
            if(iteratorA!=null){
                lenA++;
                iteratorA = iteratorA.next;
            }
            if(iteratorB!=null){
                lenB++;
                iteratorB = iteratorB.next;
            }
            
        }
        iteratorA = headA;
        iteratorB = headB;
        if(lenA>lenB){
            int diff = lenA - lenB;
            while(diff>0){
                 iteratorA = iteratorA.next;
                diff--;
            }
        }else{
            int diff = lenB - lenA;
             while(diff>0){
                 iteratorB = iteratorB.next;
                 diff--;
            }
        }
        while(iteratorA!=null){
            if(iteratorA==iteratorB){
                return iteratorA;
            }
            iteratorB = iteratorB.next;
            iteratorA = iteratorA.next;
        }
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值