当前位置: 首页 > article >正文

【双指针】三数之和

三数之和

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

文章目录

  • 三数之和
    • 题目描述
    • 算法原理
      • 解法一
      • 解法二
        • 思路如下:
        • 处理细节问题:
    • 代码编写
      • 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;

    }
};

http://www.kler.cn/a/148462.html

相关文章:

  • Python高级编程模式和设计模式
  • 鸿蒙学习基本概念
  • 传奇996_21——龙岭事件
  • 比ChatGPT更酷的AI工具
  • Spring Boot 中的全局异常处理器
  • linux设置主机名
  • 设计模式在实际业务中应用 - 模版方法
  • 万媒易发:以RPA自动化和AIGC为基础实现多平台分发
  • modbus协议及modbus TCP协议
  • 类指针压缩空间
  • 【Vue】图片切换
  • 【视觉SLAM十四讲学习笔记】第三讲——四元数
  • 一些关于开关电源经典回答
  • Java面向对象第6天
  • C 标准库 - <stdlib.h>和<string.h>详解
  • 基于mvc的大学生家教信息网站系统php+vue
  • INFINI Gateway 与华为鲲鹏完成产品兼容互认证
  • 5.golang字符串的拆解和拼接
  • 耗时一个星期整理的APP自动化测试工具大全
  • 【网络】传输层 --- 详解TCP协议
  • lv11 嵌入式开发 WDT实验 12
  • C语言:输入10个整数,写一个函数将其中最小的数和第一个数对换,把最大的数和最后一个数对换。(指针)
  • 14 网关实战:网关聚合API文档
  • 基于51单片机冰箱温度控制器设计
  • Sass混合器的详细使用教程
  • squid代理服务器(传统代理、透明代理、反向代理、ACL、日志分析)