优选算法——双指针8(单调性)

本期知识点导图

1.上期参考代码

cpp 复制代码
class Solution {
public:
    vector<vector<int>> jiayou(vector<int>& nums) {
        int n = nums.size();
        sort(nums.begin(), nums.end());//排序
        vector<vector<int>> ret;
       for(int i=0;i<n;)//这里语句可以为空,for循环固定i
       {
          int left =i+1;
          int right =n-1;
          int target=-nums[i];
            //小优化
          if(nums[i]>0)//这里可以写>=0吗?
          break;
          //找两数之和
          while(left<right)
         {
            int s=nums[left]+nums[right];
           
            if(s<target) left++;
            else if(s>target)right--;
            else 
            {
            ret.push_back({nums[i],nums[left],nums[right]});
            left++;
            right--;
            while(left<right&&nums[left]==nums[left-1])left++;//去重,注意防越界
            while(left<right&&nums[right]==nums[right+1])right--;//这里判断条件要注意
            }
         }
         i++;//为什么不能在for里面自增?
         while(i<n&&nums[i]==nums[i-1]) i++;//同理去重i,注意防越界
       }
       return ret;
    }
};

新手同学,如果看了前几期博客的话,应该是有思路的,但是动手写就是很难写出来,很正常,但越是难,我们越是要对它进行脱敏,关关难过,我们关关过,练多了自然就熟练了~~

2.本期题目解析

四数之和(点击跳转)

重点:

随机数找四元组

四数之和为目标值

要去重

孩子们,熟悉的味道又来了,俄罗斯套娃,会三数之和,就一定会这道题目,至少思路上没问题。但是煮波还是将这题拿了出来,一是题目比较锻炼代码实现能力 ,作为巩固练习非常合适,二是题目中有几个要注意的点,非常阴,我想拿来折磨一下你们,嘻

3.思路讲解

3.1暴力解法

排序加穷举

  • 先用sort 接口将原数组排序

    当数组呈升序 ,方便后边的去重 操作(重复元素相邻

  • 遍历所有四元组,找到满足条件的四元组,通过push_back接口,放到ret中去

  • 不管是暴力解还是优解,都要进行去重操作

cpp 复制代码
class Solution {
public:
    vector<vector<int>> hajiminanbeilvdou(vector<int>& nums) {
        int n = nums.size();
        // 排序
        sort(nums.begin(), nums.end());
        vector<vector<int>> ret;        
        for (int i = 0; i < n - 3; i++) {
            // 去重i
            if (i > 0 && nums[i] == nums[i-1]) continue;
            for (int j = i + 1; j < n - 2; j++) {
                // 去重j:
                if (j > i + 1 && nums[j] == nums[j-1]) continue;
                for (int k = j + 1; k < n - 1; k++) {
                    // 去重k
                    if (k > j + 1 && nums[k] == nums[k-1]) continue;
                    for (int l = k + 1; l < n; l++) {
                        // 去重l:
                        if (l > k + 1 && nums[l] == nums[l-1]) continue;   
                        if (nums[i] + nums[j] + nums[k] + nums[l] == 0) {
                            ret.push_back({nums[i], nums[j], nums[k], nums[l]});
                        }
                    }
                }
            }
        }
        return ret;
    }
};

O(N^4)的复杂度必然超时

3.2双指针

思路同三数之和一样,只是多了个循环,多了个去重,多了个减法运算(算出三数之和的目标值),既然会三数之和了,那么大家可以自己去尝试把它写出来啦~~

不会三数之和的跳:

参考代码下期见

4.预告

我们双指针专题到这里就结束了,我们一共讲了8个小题目,大致能分成5种题型

大家做好复习工作哈

下期我们就要进入新的专题啦~

下期的题目是

长度最小的子数组(点击跳转)

明天见~

相关推荐
小淮AI1 天前
从“刷题”到“追问”:AI课堂正在重塑哪些学习旧习惯?
人工智能·学习
shehuiyuelaiyuehao1 天前
算法31,前缀和,可被k整除的子数组
数据结构·python·算法
wixzjsh1 天前
TCP通信与HTTP协议学习笔记:粘包、三次握手、四次挥手与C/S、B/S模型
学习·tcp/ip·http
ZhiMuZhiLing1 天前
拓客软件学习成本实测方法论:从注册到出第一批名单要多久
学习·流量运营·用户运营
程序员大雄学编程1 天前
微积分46. 无穷级数四大核心性质:从理论到实践的全方位解析
python·学习·微积分·学习工具
203号居民1 天前
LeetCode hot 100 — 141. 环形链表2
算法·leetcode·链表
玖玥拾1 天前
LeetCode 202 快乐数
算法·leetcode
LuminousCPP1 天前
数据结构-二叉树(六):BFS层序遍历与完全二叉树判断|复用链式队列 + (N_0=N_2+1) 性质证明
c语言·数据结构·笔记·算法·二叉树·宽度优先
指针常量1 天前
【RL系列文章】难样本学习等
学习·大语言模型·rl·后训练
ZhouDevin1 天前
算法论文/数据集3——CLD(TMLR2025)压缩训练集,仅保留对验证集有益的样本
人工智能·深度学习·算法·计算机视觉