力扣最热一百题——6.三数之和

2024-08-26 14:36
文章标签 力扣 三数 一百 最热

本文主要是介绍力扣最热一百题——6.三数之和,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

题目链接:15. 三数之和 - 力扣(LeetCode)

题目描述

示例

提示

解法一:双指针

代码分析

总结


        没啥多说的,就是最近CS根本上不了分谢谢。


题目链接:15. 三数之和 - 力扣(LeetCode)

注:下述题目描述和示例均来自力扣

题目描述

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != 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
  • -10^5 <= nums[i] <= 10^5

解法一:双指针

  1. 排序

    • 首先,将数组 nums 进行排序。这是因为排序可以简化处理逻辑,使得我们可以使用双指针技术来高效地找到三数之和为零的组合。
  2. 遍历和去重

    • 使用一个 for 循环遍历数组 nums。对于每个元素 nums[i],我们尝试找到另外两个元素 nums[left]nums[right],使得它们的和与 nums[i] 的和为零。
    • 在遍历时,首先检查当前元素 nums[i] 是否大于零。如果 nums[i] 大于零,则直接返回结果,因为后面的所有元素也都大于零,不可能再找到和为零的三元组。
    • 为了避免重复的三元组,使用一个去重机制。如果当前元素与前一个元素相同,跳过当前元素。
  3. 双指针查找

    • 初始化两个指针 leftright,分别指向 i 之后的第一个元素和数组的最后一个元素。
    • 进入 while 循环,通过移动 leftright 指针来寻找满足条件的三元组。
      • 如果 nums[i] + nums[left] + nums[right] 大于零,则 right 向左移动以减少总和。
      • 如果小于零,则 left 向右移动以增加总和。
      • 如果等于零,则找到了一个满足条件的三元组,将其加入结果列表中。
  4. 处理重复元素

    • 在找到一个有效三元组后,为了避免结果中出现重复的三元组,需要对 leftright 指针所指向的元素进行去重处理。
    • 移动 left 指针,跳过所有与下一个元素相同的值。
    • 移动 right 指针,跳过所有与上一个元素相同的值。
  5. 返回结果

    • 最终返回存储所有三元组的 result 列表。

代码分析

  • 时间复杂度O(n^2)。排序的时间复杂度是 O(n log n),而双指针查找的时间复杂度是 O(n^2),因为每次内层 while 循环最多遍历整个数组。

  • 空间复杂度O(1)(不包括返回结果空间)。算法只使用了固定数量的额外空间来存储指针和变量。

class Solution {public List<List<Integer>> threeSum(int[] nums) {//创建需要返回的集合ArrayList<List<Integer>> result = new ArrayList<>();//将数组nums进行排序Arrays.sort(nums);for (int i = 0; i < nums.length; i++) {//排序之后如果第一个数已经大于0,则已经不可能使和为0if (nums[i] > 0){return result;}//防止重复元素加入,现在进行去重操作if (i > 0 && nums[i] == nums[i - 1]){//发现为重复元素,跳过这次循环continue;}//定义left和right两个指针int left = i + 1;int right = nums.length - 1;//开始查找合适的集合元素while ( left < right){if (nums[i] + nums[left] + nums[right] > 0){//大于0,right左移\right--;}else if (nums[i] + nums[left] + nums[right] < 0){//小于0,left右移\left++;}else {//获得正确目标,将目标加入result集合result.add(Arrays.asList(nums[i] , nums[left] , nums[right] ));//同时在加入之后防止找到重复的目标,进行while中的去重操作while (left < right && nums[left] == nums[left + 1]){//left重复,将left右移left++;}while (left < right && nums[right] == nums[right - 1]){//right重复,将right左移right--;}//去重操作完毕,将继续while遍历,寻找目标值,移动left和rightleft++;right--;}}}return result;}
}

总结

        多多熟悉就好啦!!!今天也开学了,我也刚发布了一篇图像识别的文章,大家多多支持谢谢!!!!!

链接如下:实时图形识别的实现:模板匹配与几何特征方法的对比-CSDN博客

感谢大家的支持!!!

这篇关于力扣最热一百题——6.三数之和的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1108840

相关文章

两数之和--力扣1

两数之和 题目思路C++代码 题目 思路 根据题目要求,元素不能重复且不需要排序,我们这里使用哈希表unordered_map。注意题目说了只对应一种答案。 所以我们在循环中,使用目标值减去当前循环的nums[i],得到差值,如果我们在map中能够找到这个差值,就说明存在两个整数的和为目标值。 如果没有找到,就将当前循环的nums[i]以及下标i放入map中,以便后续查

力扣第347题 前K个高频元素

前言 记录一下刷题历程 力扣第347题 前K个高频元素 前K个高频元素 原题目: 分析 我们首先使用哈希表来统计数字出现的频率,然后我们使用一个桶排序。我们首先定义一个长度为n+1的数组,对于下图这个示例就是长度为7的数组。为什么需要一个长度为n+1的数组呢?假如说总共有三个数字都为1,那么我们需要把这个1放在数组下标为3的位置,假如说数组长度为n,对于这个例子就是长度为3,那么它的

【数据结构与算法 | 灵神题单 | 删除链表篇】力扣3217, 82, 237

总结,删除链表节点问题使用到列表,哈希表,递归比较容易超时,我觉得使用计数排序比较稳,处理起来也不是很难。 1. 力扣3217:从链表中移除在数组中的节点 1.1 题目: 给你一个整数数组 nums 和一个链表的头节点 head。从链表中移除所有存在于 nums 中的节点后,返回修改后的链表的头节点。 示例 1: 输入: nums = [1,2,3], head = [1,2,3,

力扣 739. 每日温度【经典单调栈题目】

1. 题目 理解题意: 1.1. 给一个温度集合, 要返回一个对应长度的结果集合, 这个结果集合里面的元素 i 是 当前 i 位置的元素的下一个更高温度的元素的位置和当前 i 位置的距离之差, 若是当前元素不存在下一个更高温度的元素, 则这个位置用0代替; 2. 思路 本题用单调栈来求解;单调栈就适用于来求当前元素左边或者右边第一个比当前元素大或者小的元素;【单调栈:让栈中的元素保持单调

力扣接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]输出:6解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 示例 2: 输入:height

每日一题,力扣leetcode Hot100之238.除自身以外数组的乘积

乍一看这个题很简单,但是不能用除法,并且在O(N)时间复杂度完成或许有点难度。 考虑到不能用除法,如果我们要计算输出结果位置i的值,我们就要获取这个位置左边的乘积和右边的乘积,那么我新设立两个数组L和R。 对于L来说,由于表达的是位置i左边的数的乘积,那么L[0]=1,因为第一个数字左边没数那么为了不影响乘积初始值就设置为1,那么L[1]=L[0]*nums[0],那么L[i]=L[i-1

力扣 797. 所有可能路径【DFS】

1. 题目 2. 代码 DFS , 直接见代码 class Solution {public:vector<int> path;vector<vector<int>> res; // 结果集void dfs(vector<vector<int>>& graph, int cur, int n){// 找出所有从节点 0 到节点 n-1 的路径// 下标从 0 开始的if (

【LeetCode】最接近的三数之和

题目要求 解题思路 这道题解题方法和三数之和解题思路一样,可以参考上一篇博客 代码实现 class Solution {public:int threeSumClosest(vector<int>& nums, int target) {//排序sort(nums.begin(),nums.end());int len=nums.size();//固定一个,利用双指针解决int c

Java中等题-整数替换(力扣)

给定一个正整数 n ,你可以做如下操作: 如果 n 是偶数,则用 n / 2替换 n 。如果 n 是奇数,则可以用 n + 1或n - 1替换 n 。 返回 n 变为 1 所需的 最小替换次数 。 示例 1: 输入:n = 8输出:3解释:8 -> 4 -> 2 -> 1 示例 2: 输入:n = 7输出:4解释:7 -> 8 -> 4 -> 2 -> 1或 7 ->

力扣 | 递归 | 区间上的动态规划 | 486. 预测赢家

文章目录 一、递归二、区间动态规划 LeetCode:486. 预测赢家 一、递归 注意到本题数据范围为 1 < = n < = 20 1<=n<=20 1<=n<=20,因此可以使用递归枚举选择方式,时间复杂度为 2 20 = 1024 ∗ 1024 = 1048576 = 1.05 × 1 0 6 2^{20} = 1024*1024=1048576=1.05 × 10^