C++ 优先算法 —— 四数之和(双指针)

目录

题目:四数之和

1. 题目解析

2. 算法原理

Ⅰ. 暴力枚举

Ⅱ. 双指针算法

不漏的处理:

去重处理:

3. 代码实现

Ⅰ. 暴力枚举

Ⅱ. 双指针算法


题目:四数之和

1. 题目解析

题目截图:

这道题与三数之和(三数之和的解答)及两数之和(两数之和的解答)是很相似的,这道题目要求,也类似于三数之和,它这里的顺序上:

  • 每个四元组的前后顺序可以任意
  • 每个四元组中的数据顺序可以任意

这里target可以不同(target可以随意)。

 

 

2. 算法原理

这里也是同样有两种解法:

  • 暴力枚举
  • 双指针算法

Ⅰ. 暴力枚举

这里方法也是:排序+暴力枚举(从左往右)+去重

类比前面的三数之和:

//伪代码演示
for (int i = 0; i < n; i++) // 固定一个数afor (int j = i + 1; j < n; j++)     //依次固定枚举第二个数for (int k = j + 1; k < n; k++)    //枚举第三个数for(int z = k + 1; z < n; z++)    //枚举第四个数查找符合的四元组,去重...

 这里套了四层for循环,时间复杂度就是O(N⁴)。(会出现超时问题)

Ⅱ. 双指针算法

这里同三数之和也是:排序+双指针+去重

这里就相当于划分成,固定第一个数,剩下的就是利用三数之和思想解决,三数之和中,也是要固定一个数(这里也就是第二个数),接着利用两数之和解决,也就是在剩下的区间内用双指针算法。

总结一下解决方法: 

  1. 依次固定一个数a(从左往右固定a,固定枚举完这一个后,再换下一个)。
  2. 在a的后面的区间内,利用“三数之和”的思想,找到三个数,使这三个数的和等于target-a即可。

这里三数之和:

  1. 依次固定一个数b。
  2. 在b后面的区间内,利用双指针,找到两个数,使这两个数的和等于target-a-b即可。

通过上图可以看到需要套两次for循环加一个while,时间复杂度为O(N²)。 

这里也是需要处理同三数之和的细节问题:

不漏的处理:

也就是确保所有符合条件的情况不漏掉,这里也是找到一种结果之后,不要停(两个指针不停),缩小区间(两指针都向内移动一步),继续寻找符合的情况。

 去重处理:

这里需要考虑三个去重情况:

 

//伪代码演示
for (i = 0; i < n; i++)  //固定数a		//利用三数之和for (j = i + 1; j < n; j++)  //固定数b//双指针while (left < right) //处理数据,并去重		//这里去重同样注意越界问题的判断:left < rightj < ni < n

接下来,实现代码。

3. 代码实现

题目链接:四数之和

Ⅰ. 暴力枚举

//这里时间复杂度:O(N⁴)
class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {// 1.排序sort(nums.begin(), nums.end());vector<vector<int>> ret; // 用来存储所有的四元组// 2.暴力枚举int n = nums.size();int i, j, k, z;for (i = 0; i < n;) // 固定一个数a{for (j = i + 1; j < n;) // 依次固定枚举第二个数{for (k = j + 1; k < n;) // 枚举第三个数{for (z = k + 1; z < n;)  // 枚举第四个数{long long sum = (long)nums[i] + nums[j] + nums[k] + nums[z];if (sum == target) {ret.push_back({nums[i], nums[j], nums[k], nums[z]});}// 去重z++z;while (z < n && nums[z] == nums[z - 1]) {++z;}}// 去重k++k;while (k < n && nums[k] == nums[k - 1]) {++k;}}// 去重j++j;while (j < n && nums[j] == nums[j - 1]) {++j;}}// 去重i++i;while (i < n && nums[i] == nums[i - 1]) {++i;}}return ret;}
};

提交记录(这里按理说会超时,时间复杂度:O(N⁴),但这里通过了):

Ⅱ. 双指针算法

//这里时间复杂度是O(N²)
class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {// 1.排序sort(nums.begin(), nums.end());vector<vector<int>> ret;int n = nums.size();// 2.利用双指针算法int i, j;for (i = 0; i < n;)  //固定数a{//利用三数之和for (j = i + 1; j < n;)  //固定数b{//双指针int left = j + 1;int right = n - 1;long long t = (long)target - nums[i] - nums[j];  //注意数据溢出问题,用long long解决while (left < right) {int sum = nums[left] + nums[right];if (sum > t) {--right;}else if (sum < t) {++left;}else {// 将获取的四元组尾插ret里ret.push_back({ nums[i], nums[j], nums[left++], nums[right--] });// 缩小区间查找// 不漏,去重// 去重left和right,注意区间越界问题while (left < right && nums[left] == nums[left - 1]) {++left;}while (left < right && nums[right] == nums[right + 1]){--right;}}}// 注意j的去重++j;while (j < n && nums[j] == nums[j - 1]) {++j;}}// 注意去重i++i;while (i < n && nums[i] == nums[i - 1]) {++i;}}return ret;}
};

提交记录:

制作不易,若有不足之处或出问题的地方,请各位大佬多多指教 ,感谢大家的阅读支持!!!   

 

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

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

相关文章

思考:linux Vi Vim 编辑器的简明原理,与快速用法之《 7 字真言 》@ “鱼爱返 说 温泉啊“ (**)

Linux vi/vim | 菜鸟教程 https://zhuanlan.zhihu.com/p/602675406 Linux Vim编辑器的基本使用_vim文本编辑器-CSDN博客 这里提出使用 vi / vim 进行简单的编辑操作的原因&#xff0c;主要是在容器镜像中&#xff0c;普遍都是使用这个。 在 linux 服务器应用场景&#x…

C# 通俗易懂的介绍基础知识(七)——栈Stack(从日常生活开始讲解)

目录 一、前言 二、栈是排列方式 三、栈的单词 四、程序中的栈 五、栈的方法 1.声明并初始化栈 2.往栈里放东西&#xff08;学名&#xff1a;入栈&#xff09; 3.从栈往外拿东西 &#xff08;学名&#xff1a;出栈&#xff09; 4.清空栈 5.遍历 Stack 6.获取Stack的长…

React Query在现代前端开发中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 React Query在现代前端开发中的应用 React Query在现代前端开发中的应用 React Query在现代前端开发中的应用 引言 React Query …

面试题之---解释一下原型和原型链

实例化对象 和普调函数一样&#xff0c;只不过调用的时候要和new连用&#xff08;实例化&#xff09;&#xff0c;不然就是一个普通函数调用 function Person () {} const o1 new Person() //能得到一个空对象 const o2 Person() //什么也得不到&#xff0c;这就是普通的…

Java项目实战II基于微信小程序的助农扶贫的设计与实现(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 随着移动互联网技术的快速发展&#xf…

【Linux】阿里云服务器搭建gradio实例

文章目录 0 前言1 整体结构2 Python开放环境搭建2.1 SSL安装2.2 python安装 3 开发3.1 工具使用3.2 gradio3.3 langchain 4 nginx部署4.1 下载安装4.2 配置访问gradio 5 服务编写6 扩展&#xff1a;安装软件步骤总结 0 前言 因为课程原因&#xff0c;需要做一个大模型相关的大作…

vue3中如何实现标准元素 拖动 功能 【收藏备用】

最近在用vue3做一个企业后台管理系统的项目,在登录页面的时候需要用户滑动滑块来获取验证码登录系统 用到了元素拖放 这里也顺便记录一下 如何使用的. 目录 1.功能介绍 2.代码部分 3 实现过程 3.1 设置可拖动元素 3.2 拖动什么 3.3 放到何处 3.4 进行放置 1.功能介绍…

小水电远程集控运维系统简介及应用价值

一、政策背景 2023年7月14日水利部办公厅印发了《智能化小型水电站技术指南( 试行)》和&#xff08;《小水电集控中心技术指南( 试行)》两个指导性文件&#xff0c;明确要求实施小水电绿色改造和现代化提升工程&#xff0c;推进建设智能集约的现代化小水电。 二、系统概述 小…

公司电脑加全屏水印怎么加(怎么打水印满屏)?4个方法精选!包教包会!

在企业管理中&#xff0c;为了保护公司机密信息的安全&#xff0c;给公司电脑添加全屏水印已成为一种常见的安全措施。 全屏水印不仅可以震慑潜在的窥探者&#xff0c;还能在信息不慎泄露时提供追溯线索。 那么&#xff0c;如何给公司电脑添加全屏水印呢&#xff1f; 以下是4…

AI大模型开发架构设计(18)——基于大模型构建企业知识库案例实战

文章目录 1 LLM 大模型在工作中的实际应用以及局限性LLM 大模型工作中实际应用大模型2点局限性 2 基于大模型和向量数据库的企业级知识库架构剖析向量数据库向量数据库选型知识库文档检索增强(Retrieval Augmented Generation)向量数据库应用技术总体架构向量数据库应用离线索引…

10款PDF合并工具的使用体验与推荐!!!

在如今的信息洪流中&#xff0c;我们几乎每个人都被淹没在大量的数字文档之中。无论是学生、教师还是职场人士&#xff0c;我们都需要高效地管理和处理这些文档。而PDF文件&#xff0c;凭借其跨平台的稳定性和通用性&#xff0c;成了最常用的文档格式之一。我们经常需要处理、编…

Redis做分布式锁

&#xff08;一&#xff09;为什么要有分布式锁以及本质 在一个分布式的系统中&#xff0c;会涉及到多个客户端访问同一个公共资源的问题&#xff0c;这时候我们就需要通过锁来做互斥控制&#xff0c;来避免类似于线程安全的问题 因为我们学过的sychronized只能对线程加锁&…

IntelliJ+SpringBoot项目实战(四)--快速上手数据库开发

对于新手学习SpringBoot开发&#xff0c;可能最急迫的事情就是尽快掌握数据库的开发。目前数据库开发主要流行使用Mybatis和Mybatis Plus,不过这2个框架对于新手而言需要一定的时间掌握&#xff0c;如果快速上手数据库开发&#xff0c;可以先按照本文介绍的方式使用JdbcTemplat…

12、Linux系统的网络基本设置

查看网络接口信息ifconfig ip addr/ip a #简单查看网络接口信息 ifconfig #表示只显示当前活跃的设备接口信息 ifconfig -a #查看当前主机所有的&#xff08;all&#xff09;网络设备&#xff0c;包括未运行的设备。 如我们查看本机网卡ens33的…

JDK1.8升级JDK不生效

最近因为项目原因&#xff0c;需要将jdk1.8升级到JDK11.升级发生了一个纠结的问题&#xff0c;就是cmd不生效。在此记录&#xff01; 项目中指定jdk 如果在android studio项目&#xff0c;可以单独指定该项目的jdk&#xff0c;而不用全局升级&#xff0c;可以做如下配置&#…

八 Bean的生命周期

八、Bean的生命周期 8.1 什么是Bean的生命周期 Spring其实就是一个管理Bean对象的工厂。它负责对象的创建&#xff0c;对象的销毁等。 所谓的生命周期就是&#xff1a;对象从创建开始到最终销毁的整个过程。 什么时候创建Bean对象&#xff1f; 创建Bean对象的前后会调用什…

【Android】webview常用方法和使用

文章目录 前言一、常见用法二、基础属性webView的常用方法WebViewClient的常用方法WebChromeClient的常用方法WebSettings的相关方法 三、加载流程和事件回调四、webview和JS之间的互相调用总结 五、参考链接 前言 最近项目又用到了webview&#xff0c;在回顾复习一次webview相…

OpenGL ES 共享上下文实现多线程渲染

OpenGL ES 共享上下文时,可以共享哪些资源? 共享上下文实现多线程渲染 EGL 概念回顾 EGL 是 OpenGL ES 和本地窗口系统(Native Window System)之间的通信接口,它的主要作用: 与设备的原生窗口系统通信; 查询绘图表面的可用类型和配置; 创建绘图表面; 在OpenGL ES 和…

09C++结构体

/*结构体属于用户自定义的数据类型&#xff0c; 允许用户存储不同的数据类型, 语法:struct 结构体名{结构体成员列表} ;*/ //struct 结构体名 变量名 #include <iostream> #include <string> using namespace std; struct student { string name; int age;int s…

python第七次作业

01.设计一个函数&#xff0c;可以传入一个或多个单词的字符串&#xff0c;并返回该字符串&#xff0c;但所有五个或更多字母的单词都前后颠倒 a input("输入:") print(a) #将一句话以空格为分界拆分为单个单词 b a.split(" ") ls_1 [] ls_2 []for i i…