算法基础学习Day4(双指针)

文章目录

1.题目

  1. LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode)
  2. 15. 三数之和 - 力扣(LeetCode)

2.题目解答

1.查找总价格为目标值的两个商品

1.1题目及题目解析

1.2算法学习

暴力解法

这里我们还是先进行暴力解法,根据暴力解法去寻找更好的算法:

直接进行枚举比对即可:

cpp 复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) {
        vector<int> end;
        for(int i =0 ;i<=price.size()-2;i++)
        {
            for(int j =i+1;j<=price.size()-1;j++)
            {
                if(price[i]+price[j]==target)
                {
                    end.push_back(price[i]);
                    end.push_back(price[j]);
                }
            }
        }
        end.resize(2);
        return end;
    }
};

当然这里是过不了的

优化算法

这里因为数组是有序的我们仍然要用指针的方法

先让left指针指向最左边,让right指针指向最右边

直接让leftright指向的数进行相加和target进行比较

会出现以下两种情况:

  1. leftright指向的数比target

    因为数组有序,当left不行时,去找比left大的数,直接让left++

  1. leftright指向的数比target

    此时就不能去移动left了,应该让right向左移动了所以应该是right--

  1. 将这两部分写成代码如下:

    cpp 复制代码
    while(left<right)
    {
        if(price[left]+price[right]>target)
        {
            right--;
        }
        else if(price[left]+price[right]<target)
        {
            left++;
        }
        else
        {
            end.push_back(price[left]);
            end.push_back(price[right]);
            break;
        }
    }

1.3代码提交

全部代码如下:

cpp 复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) {
        vector<int> end;
        int left=0,right = price.size()-1;
        while(left<right)
        {
            if(price[left]+price[right]>target)
            {
                right--;
            }
            else if(price[left]+price[right]<target)
            {
                left++;
            }
            else
            {
                end.push_back(price[left]);
                end.push_back(price[right]);
                break;
            }
        }
        return end;
    }
};

2.三数之和

2.1题目及题目解析

2.2算法学习

这里有两种解法:

  1. 解法一:排序+暴力枚举+利用set去重
  2. 解法二:排序+双指针

这里我们主要演示第二章解法,并且不用set去重:

首先先选择一个固定数,此时就会发现一个数学关系:

当剩下的两个数为固定数的相反数时,就会成立

所以后面就变成了和前一题一样的解法:找两个数的和

如图:

但是这里仍然有个问题:

如何去重?

这里有两种解决方法:

  1. 直接用容器去解决(这里我们就不在使用了)
  2. 找到第一个结果,可以让left和right跳过重复元素,同时固定的数字也要跳过重复元素,但是这里在用循环+/-时一定要注意不要越界访问

2.3代码提交

cpp 复制代码
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> vv;
        vector<int> v;
        sort(nums.begin(), nums.end());
        int i = 0;
        while (i < nums.size()) {
            if(nums[i]>0)
            {
                break;
            }
            int left = i + 1;
            int right = nums.size() - 1;
            while (left < right) 
            {
                if (nums[left] + nums[right] > (-nums[i])) 
                {
                    right--;
                } 
                else if (nums[left] + nums[right] < (-nums[i])) 
                {
                    left++;
                } 
                else 
                {
                    v.push_back(nums[i]);
                    v.push_back(nums[left]);
                    v.push_back(nums[right]);
                    vv.push_back(v);
                    v.clear();
                   left++,right--;//这里先进行++/--
                    while (left<right && nums[left] == nums[left - 1]) //这里比较就要-1
                    {
                        left++;
                    }
                    while (right>left && nums[right] == nums[right + 1]) 
                    {
                        right--;
                    }
                }
            }
            i++;
            while ( i < nums.size()&&nums[i] == nums[i - 1]) {
                i++;
            }
        }
        return vv;
    }
};
相关推荐
旖旎夜光2 小时前
Linux(4)(下)
linux·学习
敲敲了个代码5 小时前
从硬编码到 Schema 推断:前端表单开发的工程化转型
前端·javascript·vue.js·学习·面试·职场和发展·前端框架
wadesir7 小时前
Rust中的条件变量详解(使用Condvar的wait方法实现线程同步)
开发语言·算法·rust
yugi9878387 小时前
基于MATLAB实现协同过滤电影推荐系统
算法·matlab
TimberWill7 小时前
哈希-02-最长连续序列
算法·leetcode·排序算法
Morwit7 小时前
【力扣hot100】64. 最小路径和
c++·算法·leetcode
我命由我123457 小时前
SVG - SVG 引入(SVG 概述、SVG 基本使用、SVG 使用 CSS、SVG 使用 JavaScript、SVG 实例实操)
开发语言·前端·javascript·css·学习·ecmascript·学习方法
leoufung7 小时前
LeetCode 373. Find K Pairs with Smallest Sums:从暴力到堆优化的完整思路与踩坑
java·算法·leetcode
wifi chicken8 小时前
数组遍历求值,行遍历和列遍历谁更快
c语言·数据结构·算法
胡楚昊8 小时前
NSSCTF动调题包通关
开发语言·javascript·算法