前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【优选算法题练习】day3

【优选算法题练习】day3

作者头像
摘星
发布2023-10-15 15:53:06
1530
发布2023-10-15 15:53:06
举报
文章被收录于专栏:C/C++学习C/C++学习

一、15. 三数之和

1.题目简介

15. 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.解题思路

3.代码

代码语言:javascript
复制
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.运行结果

在这里插入图片描述
在这里插入图片描述

二、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 你可以按 任意顺序 返回答案 。

在这里插入图片描述
在这里插入图片描述

2.解题思路

3.代码

代码语言:javascript
复制
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.运行结果

在这里插入图片描述
在这里插入图片描述

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

1.题目简介

209. 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

在这里插入图片描述
在这里插入图片描述

2.解题思路

3.代码

代码语言:javascript
复制
//左闭右开,滑动窗口
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.运行结果

在这里插入图片描述
在这里插入图片描述

总结

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、15. 三数之和
    • 1.题目简介
      • 2.解题思路
        • 3.代码
          • 4.运行结果
          • 二、18. 四数之和
            • 1.题目简介
              • 2.解题思路
                • 3.代码
                  • 4.运行结果
                  • 三、209. 长度最小的子数组
                    • 1.题目简介
                      • 2.解题思路
                        • 3.代码
                          • 4.运行结果
                          • 总结
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档