【双指针】三数之和

三数之和

在做这道题之前,建议建议先将两数之和做完再做,提升更大~

文章目录

  • 三数之和
    • 题目描述
    • 算法原理
      • 解法一
      • 解法二
        • 思路如下:
        • 处理细节问题:
    • 代码编写
      • Java代码编写
      • C++代码编写

15. 三数之和 - 力扣(LeetCode)

题目描述

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

**注意:**答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

提示:

  • 3 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

算法原理

解法一

排序+暴力枚举+利用set去重

时间复杂度O(N^3)

解法二

排序+双指针

思路如下:
  1. 首先先排序

  2. 固定一个数字a(图中我们将第一个数作为aa<=0

  3. a的后面的区间中,利用双指针算法快速找到两个数的和等于-a即可

    双指针

    • 首先在a后面的区间中的两侧的数中分别定义left right两个指针
    • 这里关于left right的移动在下面这篇博客中有详细讲解,可以先移步学习之后再来做这道题~
处理细节问题:
  1. 去重(要避免越界
    • 找到一种结果的时候,left right指针都要跳过重复的元素
    • 当使用完一次双指针之后,i也需要跳过重复的元素
  2. 不漏
    • 在区间中寻找到一种结果之后,不能停止,继续缩小区间寻找,直至区间寻找完全。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

代码编写

Java代码编写

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        // 建立一个线性表存储答案
        List<List<Integer>> ret = new ArrayList<>();

        // 1. 排序
        Arrays.sort(nums);

        // 2. 双指针解决问题
        int n = nums.length;
        // 固定数 a
        for(int i = 0; i < n; )
        {
                // 双指针
                int left = i + 1, right = n - 1, target = -nums[i];
                while(left < right)
                {
                    int sum = nums[left] + nums[right];
                    if(sum > target) right--;
                    else if(sum < target) left++;
                    else
                    {
                        ret.add(new ArrayList<Integer>(Arrays.asList(nums[i], nums[left], nums[right])));
                        // 在最小区间继续寻找
                        left++; right--;
                        // 去重: left、 right
                        while(left < right && nums[left] == nums[left - 1])
                            left++;
                        while(left < right && nums[right] == nums[right + 1])
                            right--;
                    }
                }
                // 去重 i
                i++;
                while(i < n && nums[i] == nums[i - 1])
                    i++;
            }
            return ret;
    }
}

C++代码编写

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ret;
        // 1. 排序
        sort(nums.begin(), nums.end());
        // 2. 利⽤双指针解决问题
        int n = nums.size();
        for (int i = 0; i < n; ) // 固定数 a
        {
            if (nums[i] > 0) break; // ⼩优化
            int left = i + 1, right = n - 1, target = -nums[i];
            while (left < right)
            {
                int sum = nums[left] + nums[right];
                if (sum > target) right--;
                else if (sum < target) left++;
                else
                {
                    ret.push_back({ nums[i], nums[left], nums[right] });
                    left++, right--;
                    // 去重操作 left 和 right
                    while (left < right && nums[left] == nums[left - 1]) left++;
                    while (left < right && nums[right] == nums[right + 1])
                        right--;
                }
            }
            // 去重 i 
            i++;
            while (i < n && nums[i] == nums[i - 1]) i++;
        }
        return ret;

    }
};

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

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

相关文章

AIGC文生图及工具产品简介

AIGC&#xff0c;全称是人工智能生成内容&#xff08;Artificial Intelligence Generated Content&#xff09;是继UGC&#xff08;用户生成内容&#xff09;&#xff0c;PGC&#xff08;平台生成内容&#xff09;后&#xff0c;利用人工智能技术&#xff0c;自动生成内容的生产…

C++初阶--String类的使用

string类 在C语言中&#xff0c;我们总是用char* 的类型来创建一个变量&#xff0c;存储一个字符串&#xff1b;当我们想对它进行修改或者读写时&#xff0c;需要自我创建空间和使用string.h的库函数来进行操作它&#xff1b; 而在C中&#xff0c;C专门提供了一个头文件 stri…

Vue2问题:如何全局使用less和sass变量?

前端功能问题系列文章&#xff0c;点击上方合集↑ 序言 大家好&#xff0c;我是大澈&#xff01; 本文约2400字&#xff0c;整篇阅读大约需要4分钟。 本文主要内容分三部分&#xff0c;如果您只需要解决问题&#xff0c;请阅读第一、二部分即可。如果您有更多时间&#xff…

KernelSHAP vs TreeSHAP

Kernel SHAP和Tree SHAP都用于近似Shapley值。Tree SHAP要快得多。缺点是它只能用于基于树的算法&#xff0c;如随机森林和xgboost。另一方面&#xff0c;Kernel SHAP是模型不可知的(model agnostic)&#xff0c;这意味着它可以与任何机器学习算法一起使用。我们将比较这两种近…

基于图像识别的垃圾分类

基于机器学习的垃圾分类 摘要&#xff1a;2019年垃圾分类由上海开始实施&#xff0c;继而向全国推行&#xff0c;主要将垃圾种类进行划分&#xff0c;其分类包括可回收、厨余、有害和其他。本文以垃圾分类为核心展开系列探究&#xff0c;使用机器学习对垃圾进行分类&#xff0…

java中IO知识点概念

这里写自定义目录标题 内存中的数据以电子信号的形式表示&#xff0c;而磁盘中的数据是以磁场的方向表示。1.流的分类2.File类3.流的API 关键4.理解缓冲的作用-一次性多拿些读写文件的时候为什么要有缓冲流 -意义是什么缓冲流的使用 5.路径问题6.文件的创建7.内存和磁盘存储本质…

QT中的 容器(container)-大全

一、介绍 Qt库提供了一套通用的基于模板的容器类&#xff0c;可以用这些类存储指定类型的项。比如&#xff0c;你需要一个大小可变的QString的数组&#xff0c;则使用QVector<QString>。 这些容器类比STL&#xff08;C标准模板库&#xff09;容器设计得更轻量、更安全并…

i已学赋能智慧教育时代的幼儿教育

伴随“教育数字化战略行动”的深入开展,智慧教育正式成为国家战略。智慧教育延伸至家校社教育的每个阶段。当前,为适应智慧教育发展趋势,我国制定了《中国教育现代化2035》《教育部关于加强“三个课堂”应用的指导意见》《教育信息化2.0行动计划》等文件。幼儿作为智慧教育、智…

Blazor Select 实现点击一次选项触发一次后台事件

Blazor的官方案例中&#xff0c;Select组件只有两个事件 1、OnSelectedItemChanged 每次选项的时候改变触发&#xff0c;如果你点击同一个选项是不会触发后台的方法的 2、OnBeforeSelectedItemChange 我们可以用这个事件实现每次点击同一个选项都可以触发后台事件 需要注意下最…

OCR文字识别工具 Cisdem OCRWizard激活最新 for Mac

为了提高内容识别的准确性&#xff0c;Cisdem OCRWizard提供供您选择两种模式&#xff1a;文件或名片。此外&#xff0c;它会自动分析的内容&#xff0c;标志着不同颜色的页面上几个区域根据给定部分的性质&#xff1a;文本&#xff08;绿色标记&#xff09;&#xff0c;图像&a…

Stable Diffusion绘画系列【3】:二次元动漫画风

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

单片机BootLoader是咋回事?

BootLoader的定义&#xff1a; CPU进入APP之前运行的一小段程序代码就叫做BootLoader。它是由程序员编写的&#xff0c;作用是更新应用程序。这也就说明了只有BootLoader的单片机才可以升级。有的产品有升级的需要就需要BootLoader了。 单片机的启动过程可以这么叙述&#xff…

ArrayList源码全面解析

一、概述 ArrayList 是 java 集合框架中比较常用的数据结构,继承自 AbstractList&#xff0c;实现了 List 接口。底层采用数组来实现。ArrayList 实现了java.io.Serializable接口&#xff0c;这意味着ArrayList支持序列化&#xff0c;能通过序列化去传输。 1.1、底层数据结构…

fiddler设置手机端抓包看这篇文章就足够了,轻松解决!

fiddler设置手机端抓包 安卓手机抓包 第一步&#xff1a;配置电脑和安卓的相关设置 1、手机和fiddler位于同一个局域网内&#xff1b;首先从fiddler处获取到ip地址和端口号&#xff1a; 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; &#xff0c;点…

10年资深码农,聊聊程序员的35岁危机

程序员的一天&#xff0c;日常都在做什么&#xff1f; 很多外行以及初入 IT 行业的从业者&#xff0c;往往只看到了高薪、加班、敲代码的标签&#xff0c;那程序员的日常究竟是什么样的&#xff1f; 当代程序员的一天&#xff1a;聊天、开会、写代码 哪种技术最热门与能拿到高…

Shell编程基础 – for循环

Shell编程基础 – for循环 Shell Scripting Essentials - for Loop 大多数编程语言都有循环的概念和语句。如果想重复一个任务数十次&#xff0c;无论是输入数十次&#xff0c;还是输出数十次&#xff0c;对用户来说都不现实。 因此&#xff0c;我们考虑如何用好Bash Shell编…

(Spring学习06)Spring之循环依赖底层源码解析

什么是循环依赖&#xff1f; 很简单&#xff0c;就是A对象依赖了B对象&#xff0c;B对象依赖了A对象。 比如&#xff1a; // A依赖了B class A{public B b; }// B依赖了A class B{public A a; }那么循环依赖是个问题吗&#xff1f; 如果不考虑Spring&#xff0c;循环依赖并不…

浅谈STL中的分配器

分配器是STL中的六大部件之一&#xff0c;是各大容器能正常运作的关键&#xff0c;但是对于用户而言确是透明的&#xff0c;它似乎更像是一个幕后英雄&#xff0c;永远也不会走到舞台上来&#xff0c;观众几乎看不到它的身影&#xff0c;但是它又如此的重要。作为用户&#xff…

计算机缺少vcruntime140_1.dll的5个解决方法,轻松解决dll缺失问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“缺少vcruntime140_1.dll”。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;这个错误通常会导致某些应用程序无法正常运行。那么&#xff0c;如何解决缺少vcruntime140_1.dll的问…

Vue框架学习笔记——事件处理:v-on指令+methods

文章目录 前文提要事件处理的解析过程&#xff0c;v-on:事件名样例代码如下&#xff1a;效果展示图片&#xff1a;v-on:事件名"响应函数"v-on简写形式响应函数添加响应函数传参占位符"$event"注意事项 前文提要 本人仅做个人学习记录&#xff0c;如有错误…