Leet学习_001快慢指针

一、概念

快慢指针主要应用于查找链表或迭代函数中是否存在循环

定义两个相同数据结构的指针,区别在于慢指针和快指针的移动步长step可以不同。在每次迭代循环中,快指针与慢指针之间的距离可以拉开或不同,来完成我们想要的目的。

根据step设定的不同,可以区分几种情况:

(1) 快慢指针的移动距离可以相差倍数 【例1】【例2】【例3】

     step\; slow=t; step\, fast=2t;

(2) 快慢指针的移动距离可以相差固定值 【例4】

    step\; slow=t; step\, fast=t+\Delta t;

 

二、应用

例1. 【leet_876】Middle of the Linked List

使用快慢指针的典型案例,slow_step=1, fast_step=2,就可以保证当fast_step到最后节点时,slow_step到达中间节点。

fast_point=1+2t 到达最后节点,则表示链表数量为奇数,则slow_point=1+t 是中间节点。

fast_point=1+2t+1=2(1+t) 到达最后节点,表示链表数量为偶数,则slow_point=1+t 为中间节点的第一个。

class Solution {
public:
    ListNode* middleNode(ListNode* head) 
    {
        ListNode* slow_point = head;
        ListNode* fast_point = head;
        while( fast_point->next && fast_point->next->next )
        {
            slow_point=slow_point->next;
            fast_point=fast_point->next->next;
        }
        // 若数量为偶数,直接输出第一个中间节点,则如下:
        // return slow_point;	
        // 若数量为偶数,直接输出第二个中间节点,则如下:
        if(!fast_point->next)
            return slow_point;
        else 
            return slow_point->next;
    }
};

例2. 【leet_141】判断单链表中是否存在循环

代码:

class Solution {
public:
    bool hasCycle(ListNode *head) 
    {
        if(!head || !head->next || !head->next->next)
            return false;
        ListNode *fast_point = head;
        ListNode *slow_point = head;

        while(fast_point && fast_point->next)
        {
            slow_point = slow_point->next;
            fast_point = fast_point->next->next;
            if(fast_point == slow_point)
                return true;
        }
        return false;
    }
};

例3. 【leet_202】判断Happy Number

Happy Number指的是任意数字经过多次迭代后,能够为1,迭代方式如下:

是Happy Number:19 \rightarrow 1^2+9^2=82 \rightarrow 8^2+2^2=68 \rightarrow 6^2+8^2=100 \rightarrow 1^2+0^2+0^2=1
非Happy Number: 4\rightarrow4^2=16\rightarrow 1^2+6^2=37\rightarrow 3^2+7^2=58\rightarrow 5^2+8^2=89\rightarrow 8^2+9^2=145\rightarrow 1^2+4^2+5^2=42\rightarrow 4^2+2^2=20\rightarrow 2^2+0=4

代码:

class Solution {
public:
    int digitSquareSum(int n) {
        int temp = n;
        int new_number=0;
        while(temp){
            new_number += pow(temp-(temp/10)*10,2);
            temp = temp/10;
        }
        return new_number;  
    }
    bool isHappy(int n) {
        if(n==1)
            return true;
        int slow_number = n;
        int fast_number = n;
        slow_number = digitSquareSum(slow_number);
        fast_number = digitSquareSum(fast_number); 
        fast_number = digitSquareSum(fast_number); 
        while(fast_number!=1){
            slow_number = digitSquareSum(slow_number); 
            fast_number = digitSquareSum(fast_number); 
            fast_number = digitSquareSum(fast_number); 
            if(slow_number == fast_number)
                return false;
        }
        return true; 
    }
};

例4. 【leet_019】去除链表倒数第N个结点

fast_point=t+N 到达最后节点时,slow_point=t 正好是倒数第N个结点。

边界条件: N为链表结点数量时,去除的是头节点。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) 
    {
        ListNode* slow_list = head;
        ListNode* fast_list = head;
        while(fast_list)
        {
            fast_list = fast_list->next;
            n--;
            if(n<-1)
            {
                slow_list = slow_list->next;
            }
        }
        if(n==0)
            head= head->next;
        else
            slow_list->next = slow_list->next->next;
        return head;
    }
};

 

其他快慢指针文献:

https://blog.csdn.net/qq_21815981/article/details/79833976

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值