专题一:双指针【优选算法】

双指针应用场景:

数组划分、数组分块

 

目录

 

一、移动0

 二、复写0 从后向前

  三、快乐数 链表带环

 四、盛水最多的容器 单调性+双指针

五、有效三角形个数 单调性+双指针

 六、和为s的两个数字

七、三数之和 细节多 需再练


一、移动0

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int dest = -1;
        for(int cur = 0;cur < nums.size();cur++){
            if(nums[cur])
            {
                swap(nums[++dest],nums[cur]);
            }
        }
    }
};

 二、复写0 从后向前

c

细节:当最后cur = 0时,要小心越界。

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int cur = 0,dest = -1;
        int n = arr.size();
        while(cur < arr.size())
        {
            if(arr[cur]) dest++;
            else dest += 2;
            if(dest >= n-1) break;
            cur++;
        }
        if(dest == n)
        {
            arr[n - 1] = 0;
            cur--;
            dest -= 2;
        }
        while(cur >= 0)
        {
            if(arr[cur]) arr[dest--] = arr[cur--];
            else
            {
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--;
            }
        }
    }
};

  三、快乐数 链表带环

class Solution {
public:
    int bitSum(int n)
    {
        int ret = 0;
        while(n>0)
        {
            ret += (n%10)*(n%10);
            n /= 10;
        }
        return ret;
    }
    bool isHappy(int n) {
        int slow = n, fast = bitSum(n);
        while(slow != fast)
        {
            slow = bitSum(slow);
            fast = bitSum(bitSum(fast));
        }
        return slow == 1;
    }
};

 四、盛水最多的容器 单调性+双指针

注意:高度由矮的决定。

class Solution {
public:
    int maxArea(vector<int>& height) {
        int n = height.size();
        int left = 0,right = n-1;
        int ret = 0;
        while(left < right){
            int v = min(height[left],height[right])*(right-left);

            ret = max(ret,v);

            if(height[left] < height[right]) left++;
            else right--;
        }
        return ret;
    }
};

五、有效三角形个数 单调性+双指针

核心:两小边之和大于第三边就可以组成三角形。

 

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int count = 0;
        for(int m = nums.size()-1;m >= 0;m--){
            int l = 0,r = m-1;
            while(l < r)
            {
                if(nums[l] + nums[r] > nums[m]) count += (r-l),r--;
                else l++;
            }
        }
        return count;
    }
};

 六、和为s的两个数字

出现上面这样的报错是因为编译器觉得可能没有返回值,最后随便返回一个就行。 

七、三数之和 细节多 需再练

注意:要避免越界。 

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int n = nums.size();
        sort(nums.begin(),nums.end());
        vector<vector<int>> ret;
        int i = 0;
        while(i < n){
            if(nums[i] > 0)break;
            int left = i+1,right = n-1,target = -nums[i];
            while(left < right)
            {
                int sum = nums[left]+nums[right];
                if(sum < target) left++;
                else if(sum > target) right--;
                else 
                {
                    ret.push_back({nums[i],nums[left],nums[right]});
                    left++,right--;
                    while(left < right && nums[left] == nums[left-1]) left++;
                    while(left < right && nums[right] == nums[right+1]) right--;
                } 
            }
            i++;
            while(i < n && nums[i] == nums[i-1]) i++;
        }
        return ret;
    }
};

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值