<leetcode> 2021/5/13双指针总结 No.11、No.15、No.16

1. 盛最多水的容器

在这里插入图片描述
我们先从题目中的示例开始,一步一步地解释双指针算法的过程。稍后再给出算法正确性的证明。
题目中的示例为:

[1, 8, 6, 2, 5, 4, 8, 3, 7]

在初始时,左右指针分别指向数组的左右两端,它们可以容纳的水量为 min(1, 7) * 8 = 8min(1,7)∗8=8。

此时我们需要移动一个指针。移动哪一个呢?应该移动对应数字较小的那个指针(即此时的左指针)。这是因为,由于容纳的水量是由

**两个指针指向的数字中较小值 * 指针之间的距离**

决定的。如果我们移动数字较大的那个指针,那么前者「两个指针指向的数字中较小值」不会增加,后者「指针之间的距离」会减小,那么这个乘积会减小。因此,我们移动数字较大的那个指针是不合理的。因此,我们移动 数字较小的那个指针

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/container-with-most-water/solution/sheng-zui-duo-shui-de-rong-qi-by-leetcode-solution/
来源:力扣(LeetCode)

附上本人代码:

class Solution {
public:
    int maxArea(vector<int>& height) {
        //使用双指针
        int i = 0;
        int j = height.size()-1;
        int max = 0;
        int min_h = height[0];
        while(i != j ){
            if(height[i] > height[j]){
                min_h = height[j];
                j--;
            }else{
                min_h = height[i];
                i++; 
            }
            max = min_h*(j-i+1) > max? min_h*(j-i+1):max;
        }
        return max;
    }
};

2. 三数之和

在这里插入图片描述
个人理解的leetcode的解法如下:
本是3层循环,然后采用双指针的方法把3层循环简便为2层循环,因为如果已经在确定了前两个数的前提下,第三个数将会是一个确定数。那就简化成了两层循环。

  1. 先将nums数组使用sort()函数进行排序。
  2. 第一层使用first遍历数组,然后将second的初始值设定为first+1,将third初始值设定为nums.size()-1。
  3. 如果nums[first]+nums[second]+nums[third] > 0,则third–;如果等于0,则将该组push到输出数组中。如果<0则second++;直到third=second跳出循环。
    leetcode上还有一种去重复的方法,就是在每层循环之前判断是否与前一位数相等,如果相等说明得到的三元组是重复的。

if(first > 0 && nums[first]==nums[first-1])
if(second > first+1 && nums[second]==nums[second-1])

下面附上本人的解答。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ans;
        int n = nums.size();
        sort(nums.begin(),nums.end());
        for(int first = 0;first < n;first++){
            if(first > 0 && nums[first]==nums[first-1]){  //防止重复元组
                continue;
            }
            int third = n-1;
            for(int second = first+1;second < n;second++){
                if(second > first+1 && nums[second]==nums[second-1]){  //防止重复元组
                continue;
            }
                while(second < third && nums[first]+nums[second]+nums[third] > 0){
                    third--;
                }
                if(second == third) break;
                if(nums[first]+nums[second]+nums[third] == 0){
                    ans.push_back({nums[first],nums[second],nums[third]});
                }
            }
        }
        return ans;
    }
};

3. 最接近的三数之和

在这里插入图片描述
这道题刚开始本人也没想到用双指针,还是暴力解法也能过。
然后引用leetcode上的解法(思路类似于上面三数之和):

  • 如果first+second+third>0,那么就将third向左移动一个位置;

  • 如果first+second+third<0,那么就将second向右移动一个位置。

附上本人的代码:

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        int n = nums.size();
        int ans = nums[0]+nums[1]+nums[2];
        sort(nums.begin(),nums.end());
        for(int first = 0;first < n;first++){
            if(first > 0 && nums[first] == nums[first-1]) continue;
            int m = target -nums[first];
            int second = first+1;
            int third = n-1;
            while(second < third){
                int sum = nums[first]+nums[second]+nums[third];
                if(sum == target) return sum;
                if(nums[second]+nums[third] > m) {
                	if(abs(nums[second]+nums[third]-m)<abs(ans-target)) ans = nums[first]+nums[second]+nums[third];                     
                third--;
                }
                if(nums[second]+nums[third] < m) {
                	if(abs(nums[second]+nums[third]-m)<abs(ans-target)) ans = nums[first]+nums[second]+nums[third];                     
                second++; 
                }
            }
        }
        return ans;
    }
};

双指针是面试中经常会遇到的题目,如果后序刷题还遇到双指针的 问题再继续更新。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值