【优选算法题练习】day3

文章目录

  • 一、15. 三数之和
    • 1.题目简介
    • 2.解题思路
    • 3.代码
    • 4.运行结果
  • 二、18. 四数之和
    • 1.题目简介
    • 2.解题思路
    • 3.代码
    • 4.运行结果
  • 三、209. 长度最小的子数组
    • 1.题目简介
    • 2.解题思路
    • 3.代码
    • 4.运行结果
  • 总结


一、15. 三数之和

1.题目简介

15. 三数之和
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。
【优选算法题练习】day3_第1张图片
【优选算法题练习】day3_第2张图片

2.解题思路

3.代码

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ret;
        //1.排序
        sort(nums.begin(), nums.end(), [](int& x, int& y){return x < y;});
        //2.先确定三个数中最小的那个数a,然后用双指针法去查找另外两个数b和c,使b + c = -a;
        for(int i = 0;i < nums.size() - 2; ++i)
        {

            if(i > 0 && nums[i] == nums[i - 1]) continue;
            int left = i + 1, right = nums.size() - 1;
            while(left < right)
            {
                int sum = nums[left] + nums[right];
                if(sum < -nums[i])
                {
                    left++;
                    while(left < right && nums[left] == nums[left - 1]) left++;//用while是因为可能有很多重复的数字,要去重
                }
                else if(sum > -nums[i])
                {
                    right--;
                    while(left < right && nums[right] == nums[right + 1]) right--;
                }
                else
                {

                    ret.push_back({nums[i], nums[left], nums[right]});
                    left++;
                    while(left < right && nums[left] == nums[left - 1]) left++;
                    right--;
                    while(left < right && nums[right] == nums[right + 1]) right--;
                }
            }
        }
        return ret;
    }
};

4.运行结果

【优选算法题练习】day3_第3张图片

二、18. 四数之和

1.题目简介

18. 四数之和
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n(a、b、c 和 d 互不相同)
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
【优选算法题练习】day3_第4张图片

2.解题思路

3.代码

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> ret;
        //1.排序
        sort(nums.begin(), nums.end(), [](int& x, int& y){return x < y;});
        //2.两层for循环分别确定两个元素(一个最大一个最小),再用指针法确定剩下的两个元素
        for(int i = 0;i < nums.size(); ++i)
        {
            if(i > 0 && nums[i] == nums[i - 1]) continue;
            for(int j = nums.size() - 1;j >= 0; --j)
            {
                if(j <nums.size() - 1 && nums[j] == nums[j + 1]) continue;
                long long sum1 = nums[i] + nums[j];
                int left = i + 1, right = j - 1;
                while(left < right)
                {
                    long long sum2 = nums[left] + nums[right];
                    if(sum2 < (target-sum1))
                    {
                        left++;
                        while(left < right && nums[left] == nums[left - 1]) left++;
                    }
                    else if(sum2 > (target-sum1))
                    {
                        right--;
                        while(left < right && nums[right] == nums[right + 1]) right--;
                    }
                    else
                    {
                        ret.push_back({nums[i], nums[j], nums[left], nums[right]});
                        left++;
                        while(left < right && nums[left] == nums[left - 1]) left++;
                        right--;
                        while(left < right && nums[right] == nums[right + 1]) right--;
                    }
                }
            }
        }
        return ret;
    }
};

4.运行结果

【优选算法题练习】day3_第5张图片

三、209. 长度最小的子数组

1.题目简介

209. 长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
【优选算法题练习】day3_第6张图片

2.解题思路

3.代码

//左闭右开,滑动窗口
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int ret = INT_MAX, left = 0, right = 0, sum = 0;//left左边界,right右边界
        while(right <= nums.size())
        {
            //如果元素和小鱼tar就加上right的元素,同时将right++;
            //如果right是数组最后一个位置的下一个位置(右开),那么就不存在符合条件的子数组。
            if(sum < target)
            {
                if(right == nums.size()) break;
                sum += nums[right];
                right++;
            }
            else
            {
                if(ret > (right - left))
                {
                    ret = right - left;
                }
                sum -= nums[left];
                left++;
            }
        }
        if(ret == INT_MAX) return 0;
        return ret;
    }
};

4.运行结果

【优选算法题练习】day3_第7张图片


总结

今天是算法练习的第3天。
逝者如斯夫,不舍昼夜 ,继续加油。
题目来源:力扣(LeetCode),著作权归领扣网络所有。
如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!

你可能感兴趣的:(优选算法题练习,算法,leetcode)