Leetcode——双指针

一、环形链表

  • 首先怎么判断一个链表有环?即使用双指针法slow,fast,将slow和fast先指向链表的起始位置,再将slow每次移动一个位置,fast每次移动两个位置,这样如果链表有环,slow指针和fast指针必定能在环内相遇。
  • 注:如果链表只有一个节点和两个节点怎么办?即while循环条件为fast&&fast->next存在。
  • return语句用于结束当前正在执行的函数,因此在while循环中如果slow指针和fast指针相遇即return true,否则要等到while循环结束后没有找到环return false。
class Solution{
    public:
        bool hasCycle(ListNode *head){
            ListNode *slow=head;
            ListNode *fast=head;
            while(fast&&fast->next){
                slow=slow->next;
                fast=fast->next->next;
                if(slow==fast){
                    return true;
                }
            }
            return false;
            } 
};

二、环形链表II

环形链表II

  • 在确定有环的情况下如何判断环的入口,用公式计算下
  • 首先当slow与fast相遇时slow走了x+y,fast走了x+y+n(y+z),x为head到环入口的距离,y为环入口到相遇位置的距离,z为环内相遇位置到环入口的距离。
  • 在相同时间内slow每次只移动一个位置,而fast每次移动两个位置,因此相遇时可列等式
    2(x+y)=x+y+n(y+z),化简可得x=(n-1)(y+z)+z.,有两种情况:n=1即fast跑了一圈相遇,n>1即fast跑了n圈相遇即最终x=z即可。
  • 设置两个index:index1代表head位置,index2代表fast,index1和index2每次移动一个位置,相等时即为环的入口,返回index1或者index2.
    在这里插入图片描述
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *slow=head;
        ListNode *fast=head;
        while(fast&&fast->next){
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast){
                ListNode *index1=head;
                ListNode *index2=fast;
                while(index1!=index2){
                    index1=index1->next;
                    index2=index2->next;
                }
                return index1;
            }
        }
        return NULL;
    }
};

三、有序数组的平方

977. 有序数组的平方

  • 这题有暴力法和双指针法,暴力法时间复杂度O(N+log(N)),暴力法无非就是先平方,再sort排序。
  • 数组其实是有序的,只不过平方后负数可能会变大,平方的最大值就在数组的两端,不是在左边就是在右边,因此使用双指针指向数组两端。
    注:for循环初始化时int i=0,j=k;初始化多个值时用逗号隔开,i++,j–可在循环内部写出,不一定要在括号内写,但末尾的分号不能丢。
for(int i=0,j=k;i<=j;)
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int>result(nums.size());
        int k=nums.size()-1;
        for(int i=0,j=k;i<=j;)
        {
            if(nums[i]*nums[i]<=nums[j]*nums[j]){
                result[k]=nums[j]*nums[j];
                k--;
                j--;
            }
            else{
                result[k]=nums[i]*nums[i];
                k--;
                i++;
            }
        }
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值