LeetCode - 18 四数之和

news2024/11/28 10:41:07

目录

题目来源

题目描述

示例

提示

题目解析

算法源码


题目来源

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

题目描述

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

0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。

示例

示例 1:

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


示例 2:

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

提示

  • 1 <= nums.length <= 200
  • -10^9 <= nums[i] <= 10^9
  • -10^9 <= target <= 10^9

题目解析

本题是LeetCode - 15 三数之和_伏城之外的博客-CSDN博客的拓展题。

本题是需要找出所有和为target的四元组,且四元组不能重复。看本题前,建议先将前面链接的三数之和看明白。

四数之和,相当于比三数之和多了一个数。

前面求解三数之和时,我们是固定三元组中的最小值,然后通过双指针来找匹配该最小值的其他两个数。

而四数之和的解法,和三数之和类似,只是四数之和,我们需要固定四元组中最小的两个值,然后通过双指针来找匹配这两个最小值得其他两个数。

大家和对比下面四数之和,和前面三数之和得代码,其实就是多了套了一层for循环。

本题的去重逻辑也和三数之和一样。

具体解析可以看前面链接博客。

关于本题的剪枝优化:

三数之和那题的target=0,而本题四数之和的target为一个任意值,可正,可负,可0。

前面三数之和的剪枝优化,是三元组的最小值nums[i] > 0时,则此时三元组之和必然也是>0,且后续的nums[i+1]对应的三元组之和也肯定大于0,因此当nums[i] > 0时,可以直接break掉三指针运动,达到剪枝优化效果。

但是本题四数之和,我们不能说

四元组的最小值nums[i] > target,那么此时的四元组之和也是>target

比如nums = [-4, -3, -2, -1],target = -10

四元组[-4,-3,-2,-1]中nums[i] > target的,但是此时我们不能直接break掉四指针运动,因为后续的nums[j],nums[l],nums[r]也可能是负数,即nums[i] 加上后续三个数,不一定使得i,j,l,r四元组之和变大,因此nums[i] > target,但是四元组之和也有可能 == target。

本题的剪枝优化其实也可以做,但是又局限性,即只有nums[i] > 0,即i,j,l,r指向数都是正数时,此时num[i] > target可以进行剪枝优化。

同理如果nums[j] > 0 && nums[i] + nums[j] > target,也一样可以剪枝。

JS算法源码

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[][]}
 */
var fourSum = function (nums, target) {
  const ans = [];

  nums.sort((a, b) => a - b);

  for (let i = 0; i < nums.length; i++) {
    // 去重
    if (i > 0 && nums[i] == nums[i - 1]) continue;

    for (let j = i + 1; j < nums.length; j++) {
      // 去重
      if (j > i + 1 && nums[j] == nums[j - 1]) continue;

      let l = j + 1;
      let r = nums.length - 1;

      while (l < r) {
        const sum = nums[i] + nums[j] + nums[l] + nums[r];

        if (sum > target) {
          r--;
        } else if (sum < target) {
          l++;
        } else {
          ans.push([nums[i], nums[j], nums[l], nums[r]]);

          // 去重
          while (l + 1 < r && nums[l] == nums[l + 1]) l++;
          // 去重
          while (r - 1 > l && nums[r] == nums[r - 1]) r--;

          l++;
          r--;
        }
      }
    }
  }

  return ans;
};

四数之和 - 提交记录 - 力扣(LeetCode)

Java算法源码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

class Solution {
  public List<List<Integer>> fourSum(int[] nums, int target) {
    List<List<Integer>> ans = new ArrayList<>();

    Arrays.sort(nums);

    for (int i = 0; i < nums.length; i++) {
      // 剪枝
      if (nums[i] > 0 && nums[i] > target) break;

      // 去重
      if (i > 0 && nums[i] == nums[i - 1]) continue;

      for (int j = i + 1; j < nums.length; j++) {
        // 剪枝
        if (nums[j] > 0 && nums[i] + nums[j] > target) break;

        // 去重
        if (j > i + 1 && nums[j] == nums[j - 1]) continue;

        int l = j + 1;
        int r = nums.length - 1;

        while (l < r) {
          long sum = (long) nums[i] + nums[j] + nums[l] + nums[r];

          if (sum > target) {
            r--;
          } else if (sum < target) {
            l++;
          } else {
            ArrayList<Integer> tmp = new ArrayList<>();
            Collections.addAll(tmp, nums[i], nums[j], nums[l], nums[r]);
            ans.add(tmp);

            // 去重
            while (l + 1 < r && nums[l] == nums[l + 1]) l++;
            // 去重
            while (r - 1 > l && nums[r] == nums[r - 1]) r--;

            l++;
            r--;
          }
        }
      }
    }

    return ans;
  }
}

四数之和 - 提交记录 - 力扣(LeetCode)

Python算法源码

class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        ans = []

        nums.sort()

        for i in range(len(nums)):
            # 剪枝
            if nums[i] > 0 and nums[i] > target:
                break

            # 去重
            if i > 0 and nums[i] == nums[i - 1]:
                continue

            for j in range(i + 1, len(nums)):
                # 剪枝
                if nums[j] > 0 and nums[i] + nums[j] > target:
                    break

                # 去重
                if j > i + 1 and nums[j] == nums[j - 1]:
                    continue

                l = j + 1
                r = len(nums) - 1

                while l < r:
                    total = nums[i] + nums[j] + nums[l] + nums[r]

                    if total > target:
                        r -= 1
                    elif total < target:
                        l += 1
                    else:
                        ans.append([nums[i], nums[j], nums[l], nums[r]])

                        # 去重
                        while l + 1 < r and nums[l] == nums[l + 1]:
                            l += 1

                        # 去重
                        while r - 1 > l and nums[r] == nums[r - 1]:
                            r -= 1

                        l += 1
                        r -= 1

        return ans

四数之和 - 提交记录 - 力扣(LeetCode)

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

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

相关文章

selenium.chrome怎么写扩展拦截或转发请求?

Selenium WebDriver 是一组开源 API&#xff0c;用于自动测试 Web 应用程序&#xff0c;利用它可以通过代码来控制chrome浏览器&#xff01; 有时候我们需要mock接口的返回&#xff0c;或者拦截和转发请求&#xff0c;今天就来实现这个功能。 代码已开源&#xff1a; https:/…

Spring AOP(面向切面编程)详解

文章目录 前言AOP 概述AOP的基本概念AOP 应用场景AOP 常用的接口 Spring AOP 实现方式基于XML的配置基于注解的配置 Spring AOP 的使用一、Spring 的 API 接口实现AOP二、自定义类实现AOP三、注解实现AOP 模拟实现 Spring AOP 前言 Spring 提供了功能强大IOC、AOP等功能&#…

文心一言 VS 讯飞星火 VS chatgpt (36)-- 算法导论5.3 6题

六、请解释如何实现算法 PERMUTE-BY-SORTING&#xff0c;以处理两个或更多优先级相同的情形。也就是说&#xff0c;即使有两个或更多优先级相同&#xff0c;你的算法也应该产生一个均匀随机排列。 文心一言&#xff1a; 算法 PERMUTE-BY-SORTING 是一种基于排序的随机排列算法…

【第二章:物理层】

目录 知识框架No.0 : 引言No.1 &#xff1a;通信基础一、基本概念二、两个公式lim求极限1、失真&#xff08;失去真实性&#xff09; 三、编码和调制四、数据交换方式 No.2 &#xff1a;传输介质一、导向型介质二、非导向型介质 No.3 &#xff1a;物理层设备一、中继器二、集线…

selenium:元素定位之xpath、css

元素定位是在做UI自动化测试中最重要的一环&#xff0c;要牢牢掌握定位的方法&#xff0c;才能更有效率的进行UI自动化测试。 常见的元素定位方式&#xff1a; idnametag_nameclass_namelink_textpartial_link_textxpathcss 其中id&#xff0c;name是具有唯一性的&#xff0…

高考攀升小红书热榜!互动量破千万,品牌如何毕业季营销?

光影间&#xff0c;又是一年毕业季&#xff0c;弹指之间&#xff0c;那些青葱岁月如同白驹过隙般悄然从指缝溜走。近期&#xff0c;一年一度的高考、大学毕业又来袭&#xff0c;登上各大社媒平台热搜&#xff0c;成为热门话题&#xff1b;本期&#xff0c;随小编一起运用小红书…

【C++】智能指针 学习总结 |std::shared_ptr |std::unique_ptr | std::weak_ptr

文章目录 前言一、智能指针介绍二、普通指针和智能指针的比较案例三、std::shared_ptr四、std::unique_ptr五、std::weak_ptr六、std::shared_ptr |std::unique_ptr | std::weak_ptr三大智能指针的区别 前言 参考答案&#xff1a;chatgpt 一、智能指针介绍 智能指针是C的一种…

chatgpt赋能python:Python循环执行一个函数:简单而高效的代码实现

Python循环执行一个函数&#xff1a;简单而高效的代码实现 Python是一种高级编程语言&#xff0c;非常流行&#xff0c;不仅因为它易于学习和使用&#xff0c;而且因为它的灵活性。Python编程语言有很多特性&#xff0c;其中包括使用函数模块化编程&#xff0c;这在大型项目中…

图文验证码怎么测试及自动化测试怎么解决验证码问题?

目录 前言 首先&#xff0c;来简单认识下验证码 1、验证码的由来和作用 2、验证码的存储 3、验证码的原理 如何测试验证码&#xff1f; 1、手动测试 2、自动化测试 总结&#xff1a; 前言 在对安全性有要求的软件&#xff08;系统&#xff09;中都存在验证码&#xf…

高级查询 — 连接查询

关于northwind 示例数据库 查询数据库中的表 show tables;查询表的表属性 desc xxx(表名);连接查询 1.概述 若一个查询同时涉及两个及以上的表&#xff0c;则称之为连接查询。也可以叫做多表查询。使用join关键字进行多表连接。 2.分类&#xff08;按功能&#xff09; 内连…

二阶低通滤波器(通用滤波器)

一阶低通滤波器的详细算法介绍请参看下面文章: 一阶RC算法公式和梯形图代码 PLC信号处理系列之一阶低通(RC)滤波器算法_反馈信号低通滤波器_RXXW_Dor的博客-CSDN博客1、先看看RC滤波的优缺点 优点:采用数字滤波算法来实现动态的RC滤波,则能很好的克服模拟滤波器的缺点; 1…

学院课程功能使用说明书

引子 越来越多的讲师入驻csdn&#xff0c;也有很多学员通过学院平台进行课程学习&#xff0c;我们收到越来越多用户的反馈&#xff0c;现在通过本帖子来对课程功能做一个介绍&#xff0c;简称课程功能使用说明书1.0版&#xff0c;有任何问题均可在帖子下留言。 讲师 如何成为…

Centos7部署项目

Centos7部署项目 Centos7部署项目Centos7安装gitCentos7从github拉取代码配置git配置用于提交代码的用户名配置用户邮箱生成公钥效果如下 github添加SSH key打开你的GitHub获取ssh key公钥内容验证 拉取项目新建空白文件夹拉取项目 使用Docker Compose创建项目容器创建docker-c…

DC LAB8SDC约束四种时序路径分析

DC LAB 1.启动DC2.读入设计3. 查看所有违例的约束报告3.1 report_constraint -all_violators (alias rc)3.2 view report_constraint -all_violators -verbose -significant_digits 4 (打印详细报告) 4.查看时序报告 report_timing -significant_digits 45. 约束组合逻辑(adr_i…

1句代码,挽回1000万损失

前言&#xff1a; 在企业中&#xff0c;出于数据安全和应用高可用&#xff0c;很多软件和企业会对工程文件、数据库等做自动备份和应用容灾等。一份数据或者文件会保留到很多地方&#xff0c;虽然满足了安全性的需求&#xff0c;但是会因为保存数据区间太久造成占用大量的存储成…

chatgpt赋能python:Python快速入门神器:入门教程

Python快速入门神器&#xff1a;入门教程 Python作为一种高级的编程语言&#xff0c;在近年来逐渐成为编程语言领域里面的一匹黑马&#xff0c;在数据科学、人工智能、自动化测试和WEB开发等领域都得到了广泛的应用。Python极易入门&#xff0c;使用简单&#xff0c;代码质量较…

UnityVR--组件8--Avatar骨骼映射遮罩

什么是Avatar 模型中的人物都具有结构相似的骨架&#xff0c;如果建立一个模型骨架结构的映射&#xff0c;就能将同一个动画应用于不同的模型中&#xff0c;这就是Avatar&#xff0c;实现了一种动画重定向的功能。一般使用3DMax、Maya制作并导出为.fbx的人物模型&#xff0c;在…

【MySQL】MySQL在Linux中的环境安装与基本使用

目录 一、MySQL环境的安装 1、MySQL环境安装 2、安装MySQL出现的问题 3、登录MySQl 3.1方案一 3.2方案二 4、修改MySQL配置文件 5、可选设置&#xff1a;开机自启动MySQL&#xff08;云服务器没事一般不会关机&#xff09; 二、MySQL数据库基础 1、一些概念 2、基本…

Java中进制转换的两种方法你知道吗?

目录 十进制转其他进制 其他进制转十进制 实战&#xff1a; A进制转B进制 关于大数运算可以参考躲不掉的高精度计算&#xff0c;蓝桥杯必考_高精度算法在哪些比赛考_无忧#的博客-CSDN博客 十进制转其他进制 使用 Integer.toString(int n,int radix) 方法&#xff0c;该方法…

【LeetCode】739. 每日温度

739. 每日温度&#xff08;中等&#xff09; 思路 我们可以维持一个单调递减的栈&#xff0c;表示每天的温度&#xff1b;为了方便计算天数差&#xff0c;这里存放位置&#xff08;下标&#xff09;&#xff0c;而非温度本身。因为温度可以通过访问数组下标获取。 从左向右遍历…