【算法与数据结构】18、LeetCode四数之和

文章目录

  • 一、题目
  • 二、解法
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、题目

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

二、解法

  思路分析:本题的解法借助了【算法与数据结构】15、LeetCode三数之和的算法思想。首先我们进行排序,然后检查输入数据的合法性,小于四个元素直接退出,明显不存在四元组的情况也直接退出。最外面的循环从0开始,然后我们将找 四元组和为target 的任务分解成找三元组和为target_three的任务,接下来就是三元组和为目标值的算法。
  程序如下

class Solution {
public:
	vector<vector<int>> fourSum(vector<int>& nums, int target_four) {
		sort(nums.begin(), nums.end());	// 升序排列
		//my_print1(nums, "排序后数组");
		vector<vector<int>> result;
		int n = nums.size();
		// 检查合法性
		if (n < 4) return result;	// 元素小于四个 返回
		// Target小于最小四元组的和或者大于最大四元组的和 返回	
		// 需要强转成double类型,否则int会溢出, \为代码换行符,表示上下两行属于同一行
		if ((double)target_four < (double)nums[0] + (double)nums[1] + (double)nums[2] + (double)nums[3] || \
			(double)target_four >(double)nums[n - 4] + (double)nums[n - 3] + (double)nums[n - 2] + (double)nums[n - 1]) \
			return result;

		for (int j = 0; j < n; ++j) {
			if (j > 0 && nums[j] == nums[j - 1]) continue;	// j去重
			int target_three = target_four - nums[j];	// 将找 四元组和为target 的任务 分解成 找三元组和为target_three

			for (int i = j+1; i < n; ++i) {
				if (i > j+1 && nums[i] == nums[i - 1]) continue;	// i去重 
				int right = n - 1;		// 最右端
				int temp = -nums[i] + target_three;

				for (int left = i + 1; left < n; ++left) {
					if (left > i + 1 && nums[left] == nums[left - 1]) continue;	// left去重

					while (left < right && nums[left] + nums[right] > temp) {
						--right;
						// 三者之和大于0,right收缩,一直收缩到小于等于0或者left=right为止
					}

					if (left == right)	break;	// 不存在三元组,因此break。
					if (nums[left] + nums[right] == temp) {
						result.push_back({ nums[j], nums[i], nums[left], nums[right] });
					}
				}
			}
		} 
		return result;
	}
};

复杂度分析:

  • 时间复杂度: O ( n 3 ) O(n^3) O(n3),在三数之和的基础上加上一层循环,因此是 O ( n 3 ) O(n^3) O(n3)
  • 空间复杂度: O ( 1 ) O(1) O(1)

三、完整代码

  测试代码如下,特别需要注意两个极端的数组,也是题目的边界条件,判断合法性的语句不能用int,int类型在相加是会溢出,这里我强制转换成double类型,能够存储的范围更大。

# include <iostream>
# include <string>
# include <vector>
# include <algorithm>
using namespace std;

void GeneratorVector(int arr[], int arr_len, vector<int>& v) {
	for (int i = 0; i < arr_len; i++) {
		v.push_back(arr[i]);
	}
}

void my_print1(vector<int>& v, string str) {
	cout << str << endl;
	for (vector<int>::iterator it = v.begin(); it < v.end(); ++it) {
		cout << *it << ' ';
	}
	cout << endl;
}

void my_print2(vector<vector<int>>& v, string str) {
	cout << str << endl;
	for (vector<vector<int>>::iterator vit = v.begin(); vit < v.end(); ++vit) {
		for (vector<int>::iterator it = (*vit).begin(); it < (*vit).end(); ++it) {
			cout << *it << ' ';
		}
		cout << endl;
	}
}

class Solution {
public:
	vector<vector<int>> fourSum(vector<int>& nums, int target_four) {
		sort(nums.begin(), nums.end());	// 升序排列
		//my_print1(nums, "排序后数组");
		vector<vector<int>> result;
		int n = nums.size();
		// 检查合法性
		if (n < 4) return result;	// 元素小于四个 返回
		// Target小于最小四元组的和或者大于最大四元组的和 返回	
		// 需要强转成double类型,否则int会溢出, \为代码换行符,表示上下两行属于同一行
		if ((double)target_four < (double)nums[0] + (double)nums[1] + (double)nums[2] + (double)nums[3] || \
			(double)target_four >(double)nums[n - 4] + (double)nums[n - 3] + (double)nums[n - 2] + (double)nums[n - 1]) \
			return result;

		for (int j = 0; j < n; ++j) {
			if (j > 0 && nums[j] == nums[j - 1]) continue;	// j去重
			int target_three = target_four - nums[j];	// 将找 四元组和为target 的任务 分解成 找三元组和为target_three

			for (int i = j+1; i < n; ++i) {
				if (i > j+1 && nums[i] == nums[i - 1]) continue;	// i去重 
				int right = n - 1;		// 最右端
				int temp = -nums[i] + target_three;

				for (int left = i + 1; left < n; ++left) {
					if (left > i + 1 && nums[left] == nums[left - 1]) continue;	// left去重

					while (left < right && nums[left] + nums[right] > temp) {
						--right;
						// 三者之和大于0,right收缩,一直收缩到小于等于0或者left=right为止
					}

					if (left == right)	break;	// 不存在三元组,因此break。
					if (nums[left] + nums[right] == temp) {
						result.push_back({ nums[j], nums[i], nums[left], nums[right] });
					}
				}
			}
		} 
		return result;
	}
};

int main()
{
	// 测试案例
	//int arr[] = { 1,0,-1,0,-2,2 };
	//int target = 0;
	//int arr[] = { 2, 2,2,2,2 };	
	//int target = 8;
	//int arr[] = { 1,-2,-5,-4,-3,3,3,5 };
	//int target = -11;
	//int arr[] = { 1000000000,1000000000,1000000000,1000000000 };
	//int target = 0;
	int arr[] = { -1000000000,-1000000000,1000000000,-1000000000,-1000000000 };
	int target = 294967296;
	int arr_len = sizeof(arr) / sizeof(int);	
	vector<int> nums;
	GeneratorVector(arr, arr_len, nums);
	my_print1(nums, "目标数组:");
	Solution s1;
	vector<vector<int>> result = s1.fourSum(nums, target);
	my_print2(result, "结果:");
	system("pause");
	return 0;
}

end

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数仓工具Hive 概述

Hive Hive简介Hive架构HiveSQL语法不同之处建表语句查询语句 Hive查看执行计划Hive文件格式 Hive简介 Hive是由Facebook开源&#xff0c;基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张表&#xff0c;并提供类SQL查询功能。 通过Hive可以将mapred…

JVM的内容

0、Java基础考点 1、谈谈你对Java的理解 平台无关性(一次编译&#xff0c;到处运行)GC(垃圾清理)语言特性(泛型、反射)面向对象(封装、继承、多态)类库异常处理 2、Java是如何实现平台无关性的(一处编译&#xff0c;到处运行) 编译时&#xff08;语法和语义进行检测&#xf…

c#网编实验五--WCF和TCP消息通信实验

分别编写服务端和客户端程序&#xff0c;利用基于WCF的TCP技术&#xff0c;实现在线聊天功能&#xff0c;完成在线用户列表管理&#xff0c;消息发送、接收的功能。 在同一个解决方案中&#xff0c;分别编写服务端程序和客户端程序&#xff0c;利用TCP实现简单的群聊功能。 具…

校园wifi网页认证登录入口

很多校园wifi网页认证登录入口是1.1.1.1 连上校园网在浏览器写上http://1.1.1.1就进入了校园网 使 用 说 明 一、帐户余额 < 0.00元时&#xff0c;帐号被禁用&#xff0c;需追加网费。 二、在计算中心机房上机的用户&#xff0c;登录时请选择新建帐号时给您指定的NT域&…

TOGAF10®标准中文版--(阶段C —数据架构阶段B )方法

6.5 方法 6.5.1 数据结构 数据架构应该能够处理&#xff1a; 静态数据——存储中的数据动态数据——事务或服务/API 中的数据使用中的数据——应用边界的数据&#xff08;例如&#xff0c;GUI&#xff09;开放数据——组织提供给公众使用并且自愿或合法要求提供的数据 将添…

Linux主分区,扩展分区,逻辑分区的联系和区别

基本概念 硬盘分区有三种&#xff0c; 主磁盘分区、扩展 磁盘分区、 逻辑分区。 一个 硬盘 主分区至少有1个&#xff0c;最多4个&#xff0c;扩展分区可以没有&#xff0c;最多1个。且 主分区扩展分区总共不能超过4个。 逻辑分区可以有若干个。 在windows下激活的 主分区是 …

MySQL 被 PG 干翻了。。

出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013) Stack Overflow 发布了 2023 年开发者调查报告&#xff0c;据称共计超过 9 万名开发者参与了此次调查。 完整报告包含了受访开发者画像&#xff0c;以及关于开发技术、AI、职业、社区等方面的内容。本文主要介绍关于…

stm32读取BH1750光照传感器

stm32读取BH1750光照传感器 一.序言二.BH1750指令三.IIC协议四.代码实例4.1 bh1750.c源文件4.2 bh1750.h头文件 一.序言 BH1750是用IIC协议进行数据传输的。有SCL,SDA&#xff0c;VCC,GND四根线。下图是原理图 二.BH1750指令 我们先看芯片手册的操作指令&#xff08;下图&a…

2023年网络安全竞赛——网页渗透

网页渗透 任务环境说明:  服务器场景:Server2120  服务器场景操作系统:未知(封闭靶机)  用户名:未知 密码:未知 访问服务器的网站主页,猜测后台数据库中本网页中应用的库名称长度,将长度作为flag提交; 通过扫描发现靶机开放80端口,直接访问80 尝试输入一个1,…

【设计模式】工厂模式(简单工厂模式、工厂方法模式、抽象工厂模式)详记

注&#xff1a;本文仅供学习参考&#xff0c;如有错漏还请指正&#xff01; 参考文献/文章地址&#xff1a; https://zh.wikipedia.org/wiki/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%EF%BC%9A%E5%8F%AF%E5%A4%8D%E7%94%A8%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%BD%AF%E4%BB%B…

el-table合计行单元格合并、单元格样式修改

1、目标效果 源码放在下面&#xff0c;复制粘贴即可 &#xff08;1&#xff09;合计行放在头部&#xff0c;且字体颜色变粗、合计行背景色变粗 &#xff08;2&#xff09;合计行年龄算平均值且字体颜色为绿色&#xff0c;财产算总数且字体颜色为红色 2、原理 2.1、el-table中s…

WPF 零基础入门笔记(1):WPF静态页面,布局+样式+触发器

文章目录 官方文档往期回顾零基础笔记项目实战&#xff08;已完结&#xff09; WPF项目创建为什么选net core版本 WPF 静态页面WPF 页面布局WPF样式Style样式行内样式行外样式如果是简单样式&#xff0c;可以这么写如果是复杂样式 WPF样式继承WPF触发器单条件触发器多条件触发 …

【性能测试一】性能测试概述

目录 &#x1f31f;一、性能测试的基础概念 &#x1f308;1、生活中软件相关的性能问题&#xff1f; &#x1f308;2、性能测试的概念 &#x1f308;3、性能测试与功能测试的区别&#xff1f; &#x1f308;4、什么样的软件属于性能好&#xff1f;什么样的软件属于性能不好…

网络协议TCP/IP 协议学习笔记一

T C P / I P通常被认 为是一个四层协议系统&#xff0c;每一层负责不同的功能&#xff1a; 1) 链路层&#xff0c;有时也称作数据链路层或网络接口层&#xff0c; 通常包括操作系统中的设备驱动程序和计算机 中对应的网络接口卡。它们一起处理与电缆&#xff08;或其他任何传输…

黑客常用cmd命令(window版)

1、ping命令 ping命令是一个常用的网络工具&#xff0c;用来测试和诊断网络连接状况。通过发送ICMP&#xff08;Internet控制消息协议&#xff09;数据包到目标主机&#xff0c;并接收回复的数据包&#xff0c;可以测量目标主机的可达性、平均响应时间等指标。 在Windows操作…

【C++】哈希的应用

文章目录 一、位图1. 位图的引入2. 位图的实现3. 位图的应用4. 哈希切割 二、布隆过滤器1. 布隆过滤器的引入2. 布隆过滤器的实现3. 布隆过滤器的应用4. 布隆过滤器的总结 一、位图 1. 位图的引入 我们先来看一道面试题&#xff1a; 给40亿个不重复的无符号整数&#xff0c;没…

Spring Boot 如何使用 @RequestParam 进行数据校验

Spring Boot 如何使用 RequestParam 进行数据校验 在 Web 应用程序中&#xff0c;用户提交的数据通常以请求参数的形式传递。在 Spring Boot 中&#xff0c;可以使用 RequestParam 注解来获取请求参数。但是&#xff0c;如何确保这些请求参数的有效性呢&#xff1f;在本文中&a…

APP测试面试题快问快答(五)

21. App自动化你用的什么工具&#xff1f; 框架&#xff1a;Appium 编译环境和工具&#xff1a;python3.7和PyCharm 环境&#xff1a;Android sdk 第三方模拟器&#xff1a;夜神、蓝叠等模拟器 定位工具&#xff1a;uiautomatorviewer 实时日志查看&#xff1a;ddms 22.…

智慧加油站卸油作业行为分析算法 opencv

智慧加油站卸油作业行为分析系统通过opencvpython网络模型技术&#xff0c;智慧加油站卸油作业行为分析算法实现对卸油作业过程的实时监测。当现场出现卸油作业时人员离岗&#xff0c;打电话人员抽烟等违规行为&#xff0c;灭火器未正确摆放&#xff0c;明火和烟雾等异常状态&a…

TypeScript零基础入门之背景介绍和环境安装

一、什么是TypeScript TypeScript是一种由微软开发和维护的开源编程语言。它是JavaScript的超集&#xff0c;意味着任何JavaScript程序都是一种有效的TypeScript程序。TypeScript添加了静态类型、类、接口、枚举和命名空间等概念&#xff0c;同时支持ES6特性。TypeScript被视为…