LeetCode:三数之和

文章收录于LeetCode专栏


三数之和

  给你一个包含n个整数的数组nums,判断nums中是否存在三个元素a、b、c ,并使得a + b + c = 0 ?请你找出所有和为0且不重复的三元组。
  注意:答案中不可以包含重复的三元组。
  示例 1:

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

  示例 2:

输入:nums = []
输出:[]

  示例 3:

输入:nums = [0]
输出:[]

题解

  第一步审题,给定一个数组请求其中任意不重复三个元素之和为0,题意很简单就是任意从数组中取三个元素相加要等于0,且求出所有不重复的组合。
  第二步列出所有解,首先可以使用暴力三层枚举求解,其次在两数之和基础之上使用一个hash表来换取少一层循环,最后可以使用双指针左右夹逼法来求解。

解法一(暴力枚举)

  所谓暴力枚举就是采用三层循环,每层循环取出数组中一个元素,判断三层循环取出的三个元素相加是否等于0,因为要求不包含重复的三元组,所以在判断的过程中必须要进行一次判重。

class Solution{
    public List<List<Integer>> threeSum(int[] nums){
        if(nums.length == 0){
            return Collections.emptyList();
        }
        Set<List<Integer>> res = new HashSet<>();
        for(int i=0; i<nums.length-2; i++){
            for(int j=i+1; j<nums.length-1; j++){
                for(int k=j+1; k<nums.length; k++){
                    if(nums[i] + nums[j] + nums[k] == 0){
                        List<Integer> list = Arrays.asList(nums[i], nums[j], nums[k]);
                        Collections.sort(list);
                        res.add(list);
                    }
                }
            }
        }
        return new ArrayList(res);
    }
}

解法二(hash表)

  在求解两数之和的时候使用空间换时间的方式,采用hash表来记录遍历到的元素,从而可以用于下次判断的时候使用,同样三数之和也可以使用hash表来记录一层元素,使其退化为两数之和,只是这里的目标值每次都不一样而已,同样需要对结果进行判重操作。

class Solution{
    public List<List<Integer>> threeSum(int[] nums){
        if(nums.length == 0){
            return Collections.emptyList();
        }
        Set<List<Integer>> res = new HashSet<>();
        for(int i=0; i<nums.length-1; i++){
            int target = 0 - nums[i];
            Map<Integer, Integer> map = new HashMap<>();
            for(int j=i+1; j<nums.length; j++){
                int sub = target - nums[j];
                if(Objects.nonNull(map.get(sub))){
                    List<Integer> list = Arrays.asList(nums[j], sub, nums[i]);
                    Collections.sort(list);
                    res.add(list);
                }
                map.put(nums[j], j);
            }
        }
        return new ArrayList(res);
    }
}

解法三(左右指针夹逼)

  以上两种解法因为它们消耗的时间都太高,所以表现都不尽人意。题目中没有要求元素下标,所以我们完全可以先将数组进行从小到大排序,这样一来我们就可以从左开始每次固定一个元素,再使用左右两个指针来移动获取剩下的两个元素,如果当前三数之和小于0,则说明左指针应该向右移动(已经对数组进行排序,右边元素大于左边元素);如果当前三数之和大于0,则说明右指针应该向左移动;等于0则说明找到匹配元组。
在这里插入图片描述

class Solution{
    public List<List<Integer>> threeSum(int[] nums){
        if(nums.length == 0){
            return Collections.emptyList();
        }
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList<>();
        for(int i=0; i<nums.length-2; i++){
            if(nums[i] > 0){
                // 当元素大于0,说明以后元素都大于0,三数之和不可能再为0
                break;
            }
            if(i > 0 && nums[i] == nums[i-1]){
                // 跳过重复元素
                continue;
            }
            // 左指针
            int j = i + 1;
            // 右指针
            int k = nums.length -1;
            while(j < k){
                int sum = nums[i] + nums[j] + nums[k];
                if(sum == 0){
                    res.add(Arrays.asList(nums[i], nums[j], nums[k]));
                    // 跳过重复元素
                    while(j < k && nums[j] == nums[++j]);
                    // 跳过重复元素
                    while(j < k && nums[k] == nums[--k]);
                }
                if(sum < 0){
                    // 三数之和小于0,左指针向右移动
                    // nums[j] == nums[++j] 移动且跳过重复元素
                    while(j < k && nums[j] == nums[++j]);
                }
                if(sum > 0){
                    // 三数之和大于0,右指针向左移动
                    // nums[k] == nums[--k] 移动且跳过重复元素
                    while(j < k && nums[k] == nums[--k]);
                }
            }
        }
        return res;
    }
}

  第三步分析时间复杂度和空间复杂度,暴力枚举法使用了三层循环且没有使用额外的内存空间,所以时间复杂度为O(n3),空间复杂度为O(1);hash表使用空间换时间的方法,所以时间复杂度为O(n2),空间复杂度为O(n);左右指针夹逼同样使用了两层循环所以时间复杂度为O(n2),但是没有使用额外的内存空间所以空间复杂度为O(n)。


一键三连,让我的信心像气球一样膨胀!

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

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

相关文章

proxmox宿主机安装桌面

装完proxmox启动后一般进入shell界面&#xff0c;之后都是另外一台电脑连接web管理等操作&#xff0c;一直用起来还好。不过这样需要另外一台电脑连接管理操作&#xff0c;有时候调试时毕竟还是会有些不方便&#xff0c;就想能不能在宿主机上装个桌面做这类事&#xff0c;今天用…

Python基础学习之logging模块

在Python编程中&#xff0c;日志记录&#xff08;Logging&#xff09;是一个非常重要的功能。它不仅可以帮助我们追踪和调试代码中的错误&#xff0c;还可以记录程序运行时的关键信息&#xff0c;以便后续分析和优化。Python标准库中的logging模块为我们提供了强大的日志记录功…

第07-6章 应用层详解

HTTP、SSL&#xff1a;基于TCP&#xff0c;HTTP端口:80、HTTPS&#xff08;加密&#xff09;端口&#xff1a;443&#xff1b;FTP:基于TCP&#xff0c;两类端口&#xff1a;21、20&#xff08;数据传输之前需要建立连接此时是21&#xff0c;真正传输数据时用20&#xff09;TFTP…

Linux: Netfilter 简介

文章目录 1. 前言2. Netfilter 简介2.1 Netfilter 的功能2.2 Netfilter 示例2.3 Netfilter 实现概览2.3.1 Netfilter hook 的 注册 和 注销2.3.2 Netfilter hook 的触发2.3.2.1 NF_INET_PRE_ROUTING2.3.2.2 NF_INET_LOCAL_IN2.3.2.3 NF_INET_FORWARD2.3.2.4 NF_INET_LOCAL_OUT2…

【MySQL】——用户和权限管理(二)

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

Day15-JavaWeb开发-Maven高级-分模块设计与开发继承与聚合私服

1. Maven高级-分模块设计与开发 2. Maven高级-继承与聚合 2.1 继承关系实现 2.2 版本锁定 2.3 聚合实现 3. Maven高级-私服 3.1 私服-介绍 3.2 私服-资源上传与下载 4. Web开发-完结

【mysql】深入探索mysql中的各种约束条件

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

快速的异地组网工具?

【天联】是一款能够快速搭建异地组网的工具&#xff0c;其应用场景非常广泛。 零售、收银软件应用&#xff1a;通过结合【天联】&#xff0c;医药、餐饮、商超等零售行业可以实现异地统一管理。不论是分布在不同地区的门店&#xff0c;还是总部和各个分支机构&#xff0c;都可以…

工业光源环形系列一平面无影光源特点

产品特点 ◆LED灯珠均匀排布经过漫射板特殊角度反射达到漫射效果&#xff1a; ◆光源均匀性高&#xff0c;漫射效果好。

浪漫编码:手把手教你实现校园表白墙功能

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;浪漫编码&#xff1a;手把手教你实现校园表白墙功能 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 这里写目录标题 表白墙数据准备引入MyBatis和MySQL驱动依赖…

PyGame 文字显示问题及解决方法

在 Pygame 中显示文字时可能会遇到一些问题&#xff0c;例如文字显示不清晰、字体不正确或者文字位置不准确等。以下是一些常见的问题及其解决方法&#xff0c;具体情况可以看看情况。 1、问题背景 一位用户在使用 PyGame 库进行游戏开发时&#xff0c;遇到了一个问题&#xf…

【Canvas】给图片绘制矩形以及添加文字

效果图: <!DOCTYPE html> <html lang"en"><head><title>Canvas Marker Example</title></head><body><!-- 图片 --><imgid"myImage"src图片地址alt"Image to mark"style"display: no…

植物生态化学计量主要理论和假说

1 功能关联假说 描述化学计量特征与植物生长功能的关联, 主要包括: (1) 生长速率假说(Growth Rate Hypothesis) (Sterner & Elser, 2002): 随生长速率增加, 植物N:P和C:P呈降低趋势, 而P 含量呈增加趋势。该假说有助于理解植物生长速率的调控机制, 但受其他因素调控…

Oracle Database 23ai 正式发布,超级巨兽(集关系型、向量、文档、图、缓存、分布式数据库一体的全能数据库)

Oracle23c改名为Oracle23ai&#xff0c;也意味着Oracle数据库正式从Cloud进入AI时代。Oracle23ai版本是一个超级巨兽&#xff0c;简单总结下&#xff1a; AI能力&#xff1a;内置向量数据库&#xff0c;内置ONNX模型数据处理&#xff0c;内置Text2SQL&#xff0c;内置的机器学习…

Keepalived实现LVS高可用

6.1 KeepalivedLVS集群介绍 Keepalived和LVS共同构建了一个高效的负载均衡和高可用性解决方案&#xff1a;LVS作为负载均衡器&#xff0c;负责在集群中的多个服务器间分配流量&#xff0c;以其高性能和可扩展性确保应用程序能够处理大量的并发请求&#xff1b;而Keepalived则作…

llama3 史上最强开源大模型,赶超GTP-4,逼宫OpenAI

2024年4月18日&#xff0c;Meta公司推出了开源大语言模型Llama系列的最新产品—Llama 3&#xff0c;包含了80亿参数的Llama 3 8B和700亿参数的Llama 3 70B两个版本。Meta称其为“迄今为止最强的开源大模型”。 怪兽级性能 LLaMA3 提供了不同参数规模的版本&#xff0c;以适应…

【ARM Cortex-M3指南】6:异常

文章目录 六、异常6.1 异常类型6.2 优先级定义6.3 向量表6.4 中断输入和挂起行为6.5 错误异常6.5.1 总线错误6.5.2 存储器管理错误6.5.3 使用错误6.5.4 硬件错误6.5.5 处理错误 6.6 请求管理调用和可挂起的服务调用 六、异常 6.1 异常类型 Cortex-M3内置的异常架构支持多个系…

vue快速入门(五十六)具名插槽

注释很详细&#xff0c;直接上代码 上一篇 新增内容 具名插槽基本用法 源码 App.vue <template><div id"app"><h1>被淡化的背景内容</h1><my-dialog><!-- 插槽内容 --><!-- 使用插槽的名字进行对应v-slot:可以简写为# 未命名…

nginx--rewrite

功能 Nginx服务器利用ngx_http_rewrite_module 模块解析和处理理rewrite请求&#xff0c;此功能依靠PCRE(Perl Compatible Regular Expressions)&#xff0c;因此编译之前要安装PCRE库&#xff0c;rewrite是nginx服务器的重要功能之一&#xff0c;用于实现URL的重写&#xff0…

微搭低代码入门04数据模型

目录 1 创建数据模型2 一对多3 通用选项集4 API总结 上一篇我们介绍了页面管理&#xff0c;页面是盛放组件的容器&#xff0c;组件在配置属性的时候需要进行数据绑定。数据是通过创建数据模型来进行存储&#xff0c;本篇我们介绍一下数据模型的相关操作。 1 创建数据模型 微搭…
最新文章