LeetCode【0018】四数之和

本文目录

  • 1 中文题目
  • 2 求解方法:双指针+两层循环
    • 2.1 方法思路
    • 2.2 Python代码
    • 2.3 复杂度分析
  • 3 题目总结

1 中文题目

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

  • 0 ≤ a , b , c , d < n 0 \leq a, b, c, d < n 0a,b,c,d<n
  • a 、 b 、 c a、b、c abc d d d 互不相同
  • n u m s [ a ] + n u m s [ b ] + n u m s [ c ] + n u m s [ d ] = = t a r g e t nums[a] + nums[b] + nums[c] + nums[d] == target nums[a]+nums[b]+nums[c]+nums[d]==target
  • 可以按 任意顺序 返回答案 。

示例:

输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]

提示:

  • 1 ≤ n u m s . l e n g t h ≤ 200 1 \leq nums.length \leq 200 1nums.length200
  • − 1 0 9 ≤ n u m s [ i ] ≤ 1 0 9 -10^9 \leq nums[i] \leq 10^9 109nums[i]109
  • − 1 0 9 ≤ t a r g e t ≤ 1 0 9 -10^9 \leq target \leq 10^9 109target109

2 求解方法:双指针+两层循环

2.1 方法思路

方法核心

将数组排序后,使用两层循环固定前两个数,对剩余区间使用双指针法寻找后两个数,在每一层都采用剪枝和去重优化,避免重复计算。

实现步骤
(1)对数组进行排序
(2)第一层循环固定第一个数:

  • 去重跳过重复数字
  • 最大最小和剪枝

(3)第二层循环固定第二个数:

  • 去重跳过重复数字
  • 最大最小和剪枝

(4)使用双指针寻找后两个数:

  • 计算四数之和
  • 根据和与目标值的比较移动指针
  • 找到目标时进行去重

方法示例

输入:nums = [1,0,-1,0,-2,2], target = 0排序后:[-2,-1,0,0,1,2]第一轮 i = 0 (nums[i] = -2):j = 1 (nums[j] = -1):left = 2, right = 5sum = -2 + (-1) + 0 + 2 = -1 < 0left++...直到找到 [-2,-1,1,2]第二轮 i = 1 (nums[i] = -1):j = 2 (nums[j] = 0):找到 [-1,0,0,1]...最终结果:[[-2,-1,1,2], [-1,0,0,1]]

2.2 Python代码

class Solution:def fourSum(self, nums: List[int], target: int) -> List[List[int]]:# 排序,为后续双指针和剪枝做准备nums.sort()n = len(nums)result = []# 第一层循环,固定第一个数for i in range(n-3):# 去重:跳过相同的第一个数if i > 0 and nums[i] == nums[i-1]:continue# 剪枝1:当前最小和超过target,后面的组合更大,直接结束if nums[i] + nums[i+1] + nums[i+2] + nums[i+3] > target:break# 剪枝2:当前最大和小于target,说明需要更大的第一个数if nums[i] + nums[n-3] + nums[n-2] + nums[n-1] < target:continue# 第二层循环,固定第二个数for j in range(i+1, n-2):# 去重:跳过相同的第二个数if j > i+1 and nums[j] == nums[j-1]:continue# 剪枝3:当前四数最小和超过target,内层循环可以直接breakif nums[i] + nums[j] + nums[j+1] + nums[j+2] > target:break# 剪枝4:当前四数最大和小于target,需要更大的第二个数if nums[i] + nums[j] + nums[n-2] + nums[n-1] < target:continue# 双指针查找剩余两个数left, right = j + 1, n - 1while left < right:# 计算当前四数之和curr_sum = nums[i] + nums[j] + nums[left] + nums[right]if curr_sum == target:# 找到符合条件的组合,加入结果集result.append([nums[i], nums[j], nums[left], nums[right]])# 移动左指针并去重left += 1while left < right and nums[left] == nums[left-1]:left += 1# 移动右指针并去重right -= 1while left < right and nums[right] == nums[right+1]:right -= 1elif curr_sum < target:# 和小于目标值,左指针右移left += 1else:# 和大于目标值,右指针左移right -= 1return result

2.3 复杂度分析

  • 时间复杂度: O ( n 3 ) O(n³) O(n3)
    • 排序: O ( n l o g n ) O(nlogn) O(nlogn)
    • 第一层循环: O ( n ) O(n) O(n)
    • 第二层循环: O ( n ) O(n) O(n)
    • 双指针: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)
    • 存储结果的空间:
    • 只使用常数个变量
    • 排序可以原地进行

3 题目总结

题目难度:中等
数据结构:数组
应用算法:双指针

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

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

相关文章

扫雷游戏代码分享(c基础)

hi , I am 36. 代码来之不易&#x1f44d;&#x1f44d;&#x1f44d; 创建两个.c 一个.h 1&#xff1a;test.c #include"game.h"void game() {//创建数组char mine[ROWS][COLS] { 0 };char show[ROWS][COLS] { 0 };char temp[ROWS][COLS] { 0 };//初始化数…

智慧社区可视化解决方案:科技引领社区服务与管理新篇章

随着社会的发展&#xff0c;智慧社区作为新型城镇化发展目标和社区服务体系建设的重要举措&#xff0c;正逐步改变着我们的生活方式。智慧社区通过综合运用现代科学技术&#xff0c;整合区域资源&#xff0c;提升社区治理和服务水平&#xff0c;为居民提供更为便捷、高效、安全…

Nginx 的 proxy_pass 使用简介

proxy_pass 是 Nginx 中一个非常重要的指令&#xff0c;用于将请求代理到后端服务器。本文将详细介绍 proxy_pass 的基本用法、配置示例以及一些高级用法。 1. 基本概念 1.1 proxy_pass 概述 proxy_pass 指令用于将请求转发到后端服务器。它可以用于 HTTP 和 Stream 模块&am…

在 WPF 中,如何实现数据的双向绑定?

在 WPF 中&#xff0c;数据绑定是一个非常重要的特性&#xff0c;它允许 UI 与数据源之间自动同步。双向绑定是一种常见的绑定方式&#xff0c;当数据源更新时&#xff0c;UI 会自动更新&#xff1b;同样&#xff0c;当 UI 中的元素&#xff08;如文本框&#xff09;发生改变时…

[Docker#4] 镜像仓库 | 部分常用命令

目录 什么是 Docker Registry 镜像仓库生活案例 镜像仓库分类 镜像仓库工作机制 常用的镜像仓库 私有仓库 镜像仓库命令 镜像命令[部分] 容器命令[部分] 什么是 Docker Registry 定义&#xff1a;Docker Registry 负责存储、管理和分发镜像&#xff0c;并提供了登录认…

嵌入式学习-网络高级-Day03

嵌入式学习-网络高级-Day03 基于webserver的工业数据采集 HTTP协议 http简介 http特点 http协议格式 客户端请求数据格式 请求行&#xff1a; 请求头部 空行&#xff1a; 请求体 服务器响应数据格式 webserver源码分析 postman的使用 整体流程分析 任务 html html简介 html标签…

LeetCode34:在排序数组中查找元素第一个和最后一个位置

原题地址&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须…

2024年Python最新下载安装教程,附详细图文,持续更新

大家好&#xff0c;我是Java徐师兄&#xff0c;今天为大家带来的是Python3 的下载安装教程&#xff0c;适用于所有 Python3 版本&#xff0c;感兴趣的可以看一下 文章目录 简介一、Python的下载1 网盘下载地址 (下载速度比较快&#xff0c;推荐&#xff09;2 官网下载地址 二、…

原生鸿蒙应用市场:赋能开发者全生命周期服务体验

文章目录 背景自动化检测前移&#xff1a;早发现&#xff0c;早解决技术细节&#xff1a;静态代码分析与兼容性测试应用场景 按需加载&#xff1a;优化性能&#xff0c;提升用户体验技术细节&#xff1a;模块化与懒加载实现应用场景 应用加密&#xff1a;保护应用代码安全&…

苍穹外卖 数据可视化

将营业额、用户数据、订单数据、商品销量top10数据全部使用Apache Echarts可视化&#xff0c;展现在前端&#xff0c;后端只需要按照需要的格式&#xff0c;为前端提供数据即可。 ReportController package com.sky.controller.admin;import com.sky.result.Result; import co…

漏洞与攻击技术详解

漏洞与攻击技术是网络安全领域中的重要议题&#xff0c;它们之间存在着密切的关系。以下是对漏洞与攻击技术的详细分析&#xff1a; 一、漏洞的定义与分类漏洞是指在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷&#xff0c;这些缺陷使得攻击者能够在未授权的情况下访…

kafka面试题解答(四)

5、消费者组和分区数之间的关系是怎样的&#xff1f; 消费者组数小于等于分区数&#xff0c;消费者组内每个消费者负责消费不同分区的数据&#xff0c;一个分区只能由一个组内消费者消费。 6、kafka如何知道哪个消费者消费哪个分区&#xff1f; 生产者把数据发送给各个分区&…

鸿蒙华为商城APP案例

模拟器运行效果如下&#xff1a; 鸿蒙版APP-华为商城-演示视频

C++【STL容器系列(二)】vector的模拟实现

文章目录 1. vector的结构2. vector的默认成员函数2.1构造函数2.1.1 默认构造2.1.2 迭代器构造2.1.3 用n个val初始化构造 2.2 拷贝构造2.3 析构函数2.4 operator 3. vector iterator函数3.1 begin 和 cbegin函数3.2 end() 和 cend()函数 4. vector的小函数4.1 size函数4.2 capa…

git修改当前分支名称并推送到远程仓库

git修改当前分支名称并推送到远程仓库 在Git中修改当前分支的名称可以通过两种主要方式进行&#xff1a;直接在本地修改分支名称&#xff0c;或者如果你已经推送了分支到远程仓库&#xff0c;你也需要更新远程分支的名称。以下是详细步骤&#xff1a; 修改本地分支名称 查看当…

第 8 章 - Go语言 数组与切片

在Go语言中&#xff0c;数组和切片是两种非常基础且重要的数据结构。它们都用来存储一系列相同类型的元素&#xff0c;但是它们之间存在一些关键的区别。下面我们将详细探讨数组和切片的定义、使用以及切片的动态特性。 数组的定义和使用 定义 在Go语言中&#xff0c;数组是…

Linux开发讲课49--- Linux 启动过程分析

理解运转良好的系统对于处理不可避免的故障是最好的准备。 启动过程非常简单。内核在单核上以单线程和同步状态启动&#xff0c;似乎可以理解。但内核本身是如何启动的呢&#xff1f;initrd&#xff08;initial ramdisk&#xff09; 和引导程序(bootloader)具有哪些功能&#…

vscode中执行git合并操作需要输入合并commit信息,打开的nano小型文本编辑器说明-

1.前提: VScode中的git组件执行任何合并动作的时候需要提交远程合并的commit信息,然后编辑器自动打开的是nano文本编辑器 2.nano编辑器说明: 1.保存文件:按 Ctrl + O,然后按 Enter 来保存文件。 2.退出编辑器:按 Ctrl + X,这会退出 nano。 3.剪切文本:移动光标到要剪…

Java 并发相关集合

文章目录 一、CopyOnWriteArrayList 源码1.1. 概述1.2. 思想1.3. 源码① 数据结构② 初始化③ 添加元素④ 获取元素⑤ 删除元素 二、ArrayBlockingQueue 源码2.1. 概述2.2. 思想2.3. 源码① 数据结构② 初始化③ 阻塞式获取和新增元素④ 非阻塞式获取和新增元素⑤ 指定超时时间…

Mysql个人八股总结

1.一条 SQL 查询语句是如何执行的 第一步&#xff1a;连接器 连接数据库&#xff1a;当用户发起SQL查询时&#xff0c;连接器负责与数据库建立连接&#xff0c;验证用户身份并准备执行查询。 第二步&#xff1a;查询缓存 检查查询缓存&#xff1a;在执行查询之前&#xff0…