力扣算法篇:双指针

两指针相向而行

在这里插入图片描述

反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组char[的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用O(1)的额外空间解决这一问题。
你可以假设数组中的所有字符都是ASCII码表中的可打印字符。
实例
在这里插入图片描述
题解

class Solution {
public:
    void reverseString(vector<char>& s) {
        //反转字符串
        int n = s.size();
        //双指针
        int left = 0;
        int right = n-1;
        while(true){
            if(s[left]!=s[right]){
                //交换
                swap(s[left],s[right]);
            }
            left++;
            right--;
            //党right小于等于left时结束
            if(right<=left){
                break;
            }
        }
    }
};

数组拆分

在这里插入图片描述
题解

class Solution {
public:
    int arrayPairSum(vector<int>& nums) {
        //排序然后取偶数下标对应数值之和
        sort(nums.begin(),nums.end());
        int sum = 0;
        for(int i = 0;i<nums.size();i=i+2){
            sum += nums[i];
        }
        return sum;
    }
};

在这里插入图片描述
自己实现快排(双指针思想):

class Solution {
public:
    //快排实现
    void quickSort(int *array, int left, int right){
        if(left < right)
        {
            int pivot = array[left];
            int low = left, high = right;
            while(low < high)
            {
                while(array[high] >= pivot && low < high)
                    high--;
                array[low] = array[high];
                
                while(array[low] <= pivot && low < high)
                    low++;
                array[high] = array[low];
            }
            array[low] = pivot;
            
            quickSort(array, left, low - 1);
            quickSort(array, low + 1, right);
        }
    }
    int arrayPairSum(vector<int>& nums) {
        //排序然后取偶数下标对应数值之和
        // sort(nums.begin(),nums.end());
        //快排
        quickSort(&nums[0],0,nums.size()-1);
        int sum = 0;
        for(int i = 0;i<nums.size();i=i+2){
            sum += nums[i];
        }
        return sum;
    }
};

结果:在这里插入图片描述

两数之和II:输入有序数组

一个已按照升序排列的整数数组numbers,请你从数组中找出两个数满足相加防和等于目标数 target 。
函数应该以长度为2的整数数组的形式返回这两个数的下标值。numbers 的下标从1开始计数,所以答案数组应当满足1<=answer[0]< answer[1]<= numbers.length。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
实例
在这里插入图片描述
题解:左右两个指针 两指针所指之数的和 若大于目标值 right-- 若小于目标值 left++

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        //下标从1开始 返回的时候加1即可
        //左右两个指针 两指针所指之数的和 若大于目标值 right-- 若小于目标值 left++
        int n = numbers.size();
        //数组保存答案
        vector<int> result;
        //双指针
        int left = 0;
        int right = n-1;
        while(left<right){
            if(numbers[left]+numbers[right]>target){
                //大于 数值需要减少
                right--;
                continue;
            }else if(numbers[left]+numbers[right]<target){
                //小于 数值需要增加
                left++;
                continue;
            }else{
                //相等
                result.push_back(left+1);
                result.push_back(right+1);
                break;
            }
        }
        return result;
    }
};

快慢指针 同向而行

在这里插入图片描述

移除元素

在这里插入图片描述
实例:
在这里插入图片描述
题解

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        //返回移除元素后的数组的长度 并且数组在改长度范围的元素符合要求
        //长度
        int n = nums.size();
        //快指针 慢指针
        int fast = 0;
        int slow = 0;
        for(fast = 0;fast<n;fast++){
             if(nums[fast] != val){
                //不等 赋值
                nums[slow] = nums[fast];
                //移动慢指针
                slow++;
            }
        }
        return slow;
    }
};

在这里插入图片描述

最大连续1的个数

在这里插入图片描述
题解:

class Solution {
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
        //长度 
        int n = nums.size();
        //快慢指针
        int fast = 0;
        int slow = 0;
        //使用一个变量来记录最大连续1的个数
        int maxCount = 0;
        while(fast<n){
            //找到每一段的第一个1
            while(nums[fast] == 0) {
                //不是最后一个数
                if((fast+1)<n){
                    fast++;
                }else{
                    //是最后一个数 且该值为0
                    return maxCount;
                }
            }
            //出了循环 此时fast指向了第一个1 将其下标赋值给slow
            slow = fast;
            //fast继续遍历 直到遇到0
            while(nums[fast] == 1){
                if((fast+1)<n){
                    fast++;
                }else{
                    //最后一个数 且为1
                    int num = fast - slow+1;
                    if(num>maxCount){
                        maxCount = num;
                    }
                    return maxCount;
                }
            }
            //找到连续1后的第一个0
            //此时fast指向了0
            int num = fast-slow;
            if(num>maxCount){
                maxCount = num;
            }
        }
        return maxCount;
    }
};

长度最小的子数组

在这里插入图片描述
题解:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        //长度最小的子数组
        int n = nums.size();
        //快慢指针
        int fast = 0;
        int slow = 0;
        //长度最小子数组
        int minLen = n+1;
        if(nums[fast]>=target){
            return 1;
        }
        int sum = nums[fast];
        fast++;
        while(fast<n && slow<n){
            while(sum+nums[fast]<target && (fast+1)<n){
                //更新和值
                sum += nums[fast];
                fast++;
            }
            
            if(fast+1>=n){
                if(sum+nums[fast]>=target){
                    int num = fast-slow+1;
                    if(num<minLen){
                        minLen = num;
                    }
                    //fast不能再++了 但是slow还可以
                    sum = sum + nums[fast];
                    while(sum>=target) {
                        if(slow+1<n){
                            sum -= nums[slow];
                            slow++;
                        }else{
                            //等于 最后一个数直接大于等于目标值
                            return 1;
                        }
                    }
                    //不大于了
                    num = fast-(slow-1)+1;
                    if(num<minLen){
                        minLen = num;
                    }
                    return minLen;
                }else{
                     return (minLen == n+1)?0:minLen;
                }
            }
            if(sum+nums[fast]>=target){
                //大于等于了
                int num = fast-slow+1;
                cout<<"fast:"<<fast<<"slow:"<<slow;
                if(num<minLen){
                    minLen = num;
                }
                //减少和的值
                sum = sum - nums[slow];
                slow++;
            }
        }
        return (minLen == n+1)?0:minLen;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值