【算法专题】双指针算法之18. 四数之和(力扣)

news2024/11/17 23:58:31

 欢迎来到 CILMY23的博客

🏆本篇主题为:双指针算法之18. 四数之和(力扣)

🏆个人主页:CILMY23-CSDN博客

🏆系列专栏:Python | C++ | C语言 | 数据结构与算法 | 贪心算法 | Linux | 算法专题 | 代码训练营

🏆感谢观看,支持的可以给个一键三连,点赞收藏+评论。如果你觉得有帮助,还可以点点关注


题目:

18. 四数之和 - 力扣(LeetCode)

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abc 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

题目解析:

 这道题在有二数之和和三数之和的前提上,理解起来是比较快的。

1.给了一个目标值target

2.不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] 

3.找出不重复的四元组

  • 0 <= a, b, c, d < n
  • abc 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

算法原理:

 个人感觉:感觉四数之和比三数之和难多了

首先根据前两题的经验,我们很快就能推算出,这是一题双指针算法的题目,大致思路还是跟之前一样,双指针求和,然后去重。

所以我们能写出如下代码:

class Solution
{
public:
    static vector<vector<int>> fourSum(vector<int>& nums, int target)
    {
        vector<vector<int>> ret;
        //排序数组
        sort(nums.begin(), nums.end());
        int k = nums.size() - 1; //固定k
        for (k = nums.size() - 1; k > 2;)
        {
            for (int j = k - 1; j > 1;)
            {
                int sum1 = nums[k] + nums[j];
                int left = 0;
                int right = j - 1;
                while (left < right)
                {
                    int sum2 = nums[left] + nums[right];
                    if (sum2 + sum1 == target)
                    {
                        ret.push_back({ nums[left],nums[right],nums[j],nums[k] });
                        left++;
                        right--;
                    }
                    else if (sum2 > (target - sum1))
                    {
                        right--;
                    }
                    else if (sum2 < (target - sum1))
                    {
                        left++;
                    }
                }
            }
        }
        return ret;
    }
};

第一个,我用一个sum1进行存储两个固定的数的值,sum2存储两个指针的值。

接下来是重点,我的两个指针和两个固定的值相加要和target一样,所以两个指针的值要和target-sum1进行比较。

 这个很重要,我当时和sum1比较发现是行不通的,没把target搞进去,因为我们最终是要和target目标值进行比较的。

接下来是去重,首先,是两个指针的去重,这个相对容易一些。

while (left < right && nums[left - 1] == nums[left])
{
    left++;
}
while (left < right && nums[right + 1] == nums[right])
{
    right--;
}

其次是两个固定数的去重,由于我这次去重将放在循环的末尾了,所以会有一些变化。

for (k = nums.size() - 1; k > 2;)
{
    for (int j = k - 1; j > 1;)
    {
        //......
        while (left < right)
        {
            //......
        }
        j--;
        //j去重
        while (j > 1 && nums[j + 1] == nums[j])
        {
            j--;
        }
    }
    k--;
    //k去重
    while (k > 2 && nums[k + 1] == nums[k])
    {
        k--;
    }
}

 去重前,先保证固定的数会走到下一个位置,然后再进行比较。

然后还有一个坑的点是这题

会出现一个数值过大的问题,所以要把sum1和sum2都改成long long即可。 

代码编写:

class Solution
{
public:
    static vector<vector<int>> fourSum(vector<int>& nums, int target)
    {
        vector<vector<int>> ret;
        //排序数组
        sort(nums.begin(), nums.end());
        int k = nums.size() - 1; //固定k
        for (k = nums.size() - 1; k > 2;)
        {
            for (int j = k - 1; j > 1;)
            {
                long long int sum1 = nums[k] + nums[j];
                int left = 0;
                int right = j - 1;
                while (left < right)
                {
                    long long int sum2 = nums[left] + nums[right];
                    if (sum2 + sum1 == target )
                    {
                        ret.push_back({ nums[left],nums[right],nums[j],nums[k] });
                        left++;
                        right--;
                        while (left < right && nums[left - 1] == nums[left])
                        {
                            left++;
                        }
                        while (left < right && nums[right + 1] == nums[right])
                        {
                            right--;
                        }
                    }
                    else if (sum2 > (target-sum1))
                    {
                        right--;
                    }
                    else if (sum2 < (target-sum1))
                    {
                        left++;
                    }
                }
                j--;
                //j去重
                while (j > 1 && nums[j + 1] == nums[j])
                {
                    j--;
                }
            }
            k--;
            //k去重
            while (k > 2 && nums[k + 1] == nums[k])
            {
                k--;
            }
        }
        return ret;
    }
};

🛎️感谢各位同伴的支持,本期C++算法专题就讲解到这啦,下期我们将详解滑动窗口知识点,如果你觉得写的不错的话,可以给个一键三连,点赞,收藏+评论,可以的话还希望点点关注,若有不足,欢迎各位在评论区讨论。    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1955823.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络安全威胁情报是什么,它对代工生产(OEM)意味着什么?

随着汽车数字环境的不断变化&#xff0c;网络安全基础设施及其面临的威胁也日趋复杂。 为了更好地识别、理解并最终预防这些风险&#xff0c;网络安全威胁情报&#xff08;CTI&#xff09;的管理应是一个综合多方面的过程。 以下是CTI对OEM的意义&#xff0c;以及如何利用网络…

代码随想录算法训练营第40天|LeetCode 198.打家劫舍、213.打家劫舍II、337.打家劫舍III

1. LeetCode 198.打家劫舍 题目链接&#xff1a;https://leetcode.cn/problems/house-robber/ 文章链接&#xff1a;https://programmercarl.com/0198.打家劫舍.html#算法公开课 视频链接&#xff1a;https://www.bilibili.com/video/BV1Te411N7SX 思路&#xff1a; 递推公式&a…

Profinet从站转TCP/IP协议转化网关(功能与配置)

如何将Profinet和TCP/IP网络连接通讯起来呢?近来几天有几个朋友问到这个问题&#xff0c;那么作者在这里统一说明一下。其实有一个不错的设备产品可以很轻易地解决这个问题&#xff0c;名为JM-DNT-PN。接下来作者就从该设备的功能及配置详细说明一下。 一&#xff0c;设备主要…

相机镜头移动特效视频转场模板Pr工程文件

Pr转场模板&#xff0c;相机镜头移动特效视频转场Pr工程文件 逼真的相机移动&#xff1a;具有一系列动态相机移动功能&#xff0c;包括平移、倾斜、缩放和旋转&#xff0c;为您的过渡添加逼真和引人入胜的视觉元素。 无缝集成&#xff1a;以.prproj文件形式提供&#xff0c;便…

操作系统——进程深度理解

目录 一、操作系统 1、概念 2、操作系统的结构 3、操作系统的理解 二、进程 一、操作系统 1、概念 操作系统是一个软件&#xff0c;一款进行软硬件资源管理的软件 电脑开机的时间&#xff0c;就是把操作系统加载到内存并运行的过程。 对操作系统广义的认识&#xff1a;…

PowerBI 度量值不被切片器筛选

我们有这样一张表&#xff1a; 我们用一个切片器绑定奖金表[奖金]&#xff0c;就可以用表格来联动显示数据: 现在用户有个新的需求&#xff0c;当单选某个奖金时&#xff0c;需要统计小于这个奖金数的人数。 我用了一个度量值来统计&#xff1a; 度量值 VAR selected_bonus…

全国区块链职业技能大赛样题第9套后端源码

后端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746050 前端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746216 智能合约+数据库表设计:https://blog.csdn.net/Qhx20040819/article/details/140746646 项目预览 登录 用户管理

vue3 快速入门 (五) : Flex布局

1. 如何变成Flex布局 变成Flex容器&#xff0c;只需在容器布局的节点的CSS中&#xff0c;增加display : flex .mylayout {/* 省略了其他代码 */display: flex; }2. flex direction : 方向 row : 以行排列 row-reverse &#xff1a; 以行反向排列 column &#xff1a;以列排列…

向日葵RCE复现(CNVD-2022-10270/CNVD-2022-03672)

一、环境 1.1 网上下载低版本的向日葵<2022 二、开始复现 2.1 在目标主机上打开旧版向日葵 2.2 首先打开nmap扫描向日葵主机端口 2.3 在浏览器中访问ip端口号cgi-bin/rpc?actionverify-haras &#xff08;端口号&#xff1a;每一个都尝试&#xff0c;直到获取到session值…

AJAX之原理

目录 XMLHttpRequest基本使用查询参数数据提交&#xff08;注册账号&#xff09; Promise基本语法Promise三种状态Promise链式调用 async函数和await XMLHttpRequest 基本使用 XMLHttpRequest对象用于与服务器交互 与axios关系&#xff1a;axios内部采用XMLHttpRequest与服务…

Elasticsearch:跨集群使用 ES|QL

警告&#xff1a;ES|QL 的跨集群搜索目前处于技术预览阶段&#xff0c;可能会在未来版本中更改或删除。Elastic 将努力解决任何问题&#xff0c;但技术预览中的功能不受官方 GA 功能的支持 SLA 约束。 使用 ES|QL&#xff0c;你可以跨多个集群执行单个查询。 前提&#xff1a; …

每天一个设计模式之命令模式(第二天)

交互模式中的命令模式&#xff0c;在开始记录之前&#xff0c;要讲些自己的感受&#xff0c;真真切切的感受到了悟性的瓶颈&#xff01;一共十页书&#xff0c;需要自己细细琢磨品味&#xff0c;至少三四遍才大概了解了他们间的逻辑&#xff0c;我需要调整下自己的学习思路&…

Lumos学习王佩丰Excel第七讲:认识公式与函数

一、认识Excel公式 1、运算符 运算符 作用 算术运算符 加 - 减 * 乘 / 除 % 百分比&#xff0c;相当于除以100 & 连接符&#xff0c;文本数字均可连接 ^ 乘方 比较运算符 等于 > 大于 < 小于 ≤ 小于等于 ≥ 大于等于 例1&#xff1…

python实现信号合成(DSP仿真系统)【1】

python实现信号合成(DSP仿真系统)【1】 1、效果图 2、功能结构 1、基础信号正弦波、脉冲函数、阶跃函数、斜坡函数、方波、sinc曲线、矩形波(非周期) 2、信号合成(叠加)叠加噪音 3、波形展示原始波形、叠加波形、FFT、PSD、卷积 4、各种滤波器4.1.限幅滤波器4.2.中位值滤…

【OSCP系列】OSCP靶机-BTRsys-2.1(原创)

OSCP系列靶机—BTRsys-2.1 原文转载已经过授权 原文链接&#xff1a;Lusen的小窝 - 学无止尽&#xff0c;不进则退 (lusensec.github.io) 一、主机发现 二、端口扫描 1、快速扫描 2、全端口扫描 3、服务系统探测 4、漏洞探测 80端口扫到了一些目录&#xff0c;有wordpress框…

CentOS7使用yum安装MySQL

废话不多说&#xff0c;直接上干货 1、CentOS7的yum源中默认是没有mysql的&#xff0c;我们先下载mysql的repo源 wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm 2、安装mysql-community-release-el7-5.noarch.rpm包 sudo rpm -ivh mysql-community-r…

算法通关:007时间复杂度和空间复杂度:生成相邻两数不相等的数组

生成相邻两数不相等的数组 全部代码&#xff1a; import java.util.Arrays;/*** Author: ggdpzhk* CreateTime: 2024-07-28* 随机生成数组&#xff0c;比如每个元素都在0-3之间&#xff0c;且相邻两个元素不相同*/ public class _007 {public static void main(String[] args)…

Redis:管道

1. 面试题 如何优化频繁命令往返造成的性能瓶颈&#xff1f; 问题由来 edis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。一个请求会遵循以下步骤&#xff1a; 1 客户端向服务端发送命令分四步(发送命令→命令排队→命令执行→返回结果)&#xff0c;并监听Socket…

Vue.js 2 项目实战(九):商品列表

前言 Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它的设计初衷是通过采用简洁且强大的结构&#xff0c;使前端开发变得更简单和高效。以下是对 Vue.js 的详细介绍&#xff1a; 核心特性 声明式渲染 Vue.js 使用声明式语法来描述用户界面&#xff0c;通过数据绑…

力扣刷题----42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图&#xf…