算法基础学习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;
    }
};
相关推荐
前端熊猫1 分钟前
学习HTTP Range
学习
佳小蛙30 分钟前
Java参数值传递
java·算法·排序算法
勿忘初心9130 分钟前
Android车机DIY开发之学习篇(二)编译Kernel以正点原子为例
android·arm开发·单片机·嵌入式硬件·学习·eclipse
一只鸡某37 分钟前
算法--最大公约数,最小公倍数
开发语言·c++·算法
像污秽一样42 分钟前
AI刷题-异或编码、拼凑单词 chi
c++·算法
夕洪蚀1 小时前
Java阶段四03
java·开发语言·学习
swimxu1 小时前
[ LeetCode 75 ] 283 移动零(JavaScript)
javascript·算法·leetcode
Kent_J_Truman2 小时前
【买二赠一——二分、贪心(有误)】
算法
武昌库里写JAVA2 小时前
Golang的代码压缩技术应用案例分析与研究实践
数据结构·vue.js·spring boot·算法·课程设计
吃着火锅x唱着歌2 小时前
PHP7内核剖析 学习笔记 第五章 PHP的编译与执行(1)
笔记·学习·php