快慢指针在算法题上的应用

最近在刷leetcode oj,在做题过程中发现有很多题目的解法里都用到了快慢指针,之前对这个概念接触很少,所以做以下总结:

首先考虑一个简单的问题,寻找链表的中间节点,这个问题是快慢指针应用的典型问题,java代码段如下:

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

该方法一开始将快慢指针都指向头节点,然后慢指针每次移动一步,快指针一次移动两步,直到快指针到达末尾慢指针的位置就是链表的中间节点位置。

快慢指针还有其它方面的应用,判断链表是否存在环和找出环开始的位置也是快慢指针大显身手的地方,先看判断链表是否存在环的问题,java代码如下:

public boolean hasCycle(ListNode head) {
        
        if(head == null || head.next == null)
            return false;
        
        ListNode slow = head;
        ListNode fast = head;
 
        while(fast != null && fast.next != null && fast.next.next != null){
            slow = slow.next;
            fast = fast.next.next;
 
            if(slow == fast)
                return true;
        }
 
        return false;
}
利用快慢指针,如果链表有环的话,快指针和慢指针肯定会相遇,这跟环型跑道赛跑是一个道理。

在这基础上扩展不难提出这样的问题,如果链表存在环,那么如何找到环的起点,先上java代码:

public ListNode detectCycle(ListNode head) {
        if(head == null || head.next == null)
            return null;
            
        ListNode slow = head;
        ListNode fast = head;
        ListNode begin = null;
        
        while(fast != null && fast.next != null && fast.next.next != null){
            slow = slow.next;
            fast = fast.next.next;
 
            if(slow == fast){
                slow = head;
                while(slow != fast){
                    slow = slow.next;
                    fast = fast.next;
                }
                begin = slow;
                break;
            }
        }
        return begin;
}
思路就是当快慢指针相遇的时候让慢指针指向头节点,快指针变成每次移动一步,当两个指针相遇的时候,那个节点就是环的起点。

具体可以参考以下链接:http://umairsaeed.com/2011/06/23/finding-the-start-of-a-loop-in-a-circular-linked-list/






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值