【LeetCode最详尽解答】15-三数之和 3sum

2024-06-16 12:20

本文主要是介绍【LeetCode最详尽解答】15-三数之和 3sum,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

欢迎收藏Star我的Machine Learning Blog:https://github.com/purepisces/Wenqing-Machine_Learning_Blog。如果收藏star, 有问题可以随时与我交流, 谢谢大家!

链接:

  • 15-三数之和

直觉

示例:

输入: 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]

注意输出的顺序和三元组的顺序无关。

首先,我们应该记住,解决方案集不得包含重复的三元组。考虑这个示例 [-3, 3, 4, -3, 1, 2],我们需要找到 _+_+_ = 0。如果我们先看索引 0,那么它将填充 -3(索引[0]) + 1 + 2 = 0。但是,当我们到达索引 3 时,它仍然具有相同的组合,即 -3(索引[3]) + 1 + 2 = 0。这就是重复的。因此,我们可以首先对数组进行排序来处理它。在这种情况下,它将排序为 [-3, -3, 1, 2, 3, 4],当我们遇到第二个 -3 时,我们可以跳过它。

对于 _+_+_ = 0,当我们选择第一个元素时,我们需要在剩余排序数组中找到两个元素,它们的和等于负的第一个元素值。然后它转换为一个两数之和的问题,类似于问题 167-两数之和 II-输入数组已排序,即在排序数组中找到两个数的和。在此示例中,排序后的数组将变为 [-4, -1, -1, 0, 1, 2],我们应该遍历整个数组,找到 -4 + [-1, -1, 0, 1, 2] = 0,然后 -1 + [-1, 0, 1, 2] = 0,然后跳过第二个 -1,然后 0 + [1, 2] = 0,等等。

当我们遍历整个数组时,我们还应该添加一些基本情况。如果 nums[i] > 0,那么我们中断,因为数组是递增顺序的。如果 nums[i] == nums[i-1],我们应该继续循环,因为如果我们不进行此操作,答案将重复。考虑 [-1, -1, 0, 1, 2]。对于第一个 -1,它将有 [-1, -1, 2][-1, 0, 1]。对于第二个 -1,它也将有 [-1, 0, 1],这会重复答案。因为第一个 -1 的剩余数组包含了第二个 -1 的剩余数组。

然后我们可以处理这个问题。让两个指针指向剩余数组的开始和结束位置:左指针为 i + 1,右指针为数组的末尾位置。如果这三个值小于 0,那么将 l 向右移动。如果这三个值大于 0,那么将 r 向左移动。否则,我们可以将这三个值追加到结果中。之后,我们应该增加左指针并减少右指针,因为数组不仅包含一个解决方案。然而,为了避免重复的解决方案,我们还需要做一个额外的步骤。考虑 -1[0, 0, 0, 1, 1]。如果 left+1,我们移动到第二个 0 和第一个 1。那么,因为第二个 0 与第一个 0 是相同的值,我们不能将其视为额外的解决方案。我们应该继续将左指针向右移动且不超过右指针。最后,左指针将位于第一个 1,与右指针在同一位置,它将不会进入 while l < r 循环,结果不会追加它。

方法

  1. 对数组进行排序。
  2. 遍历排序后的数组,对于每个索引,将剩余元素转换为两数之和问题。
  3. 通过在处理两数之和问题时检查 nums[l] == nums[l-1],以及在选择基值时检查 nums[i] == nums[i-1] 来避免重复的解决方案。
  4. 最后,返回结果。

复杂度

  • 时间复杂度:
    O ( n 2 ) O(n^2) O(n2)
    • 对数组进行排序需要 O ( n log ⁡ n ) O(n \log n) O(nlogn),并且在循环中使用双指针方法需要 O ( n 2 ) O(n^2) O(n2)

复杂度

  • 时间复杂度:
    O ( n 2 ) O(n^2) O(n2)

    • 对数组进行排序需要 O ( n log ⁡ n ) O(n \log n) O(nlogn),并且在循环中使用双指针方法需要 O ( n 2 ) O(n^2) O(n2),因此总体时间复杂度为 O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度:
    O ( n ) O(n) O(n)

    • 如果不考虑用于存储输出的空间,空间复杂度为 O ( 1 ) O(1) O(1)。排序是就地完成的,只使用常量量的额外空间。

代码

class Solution(object):def threeSum(self, nums):""":type nums: List[int]:rtype: List[List[int]]"""nums.sort()result = []for i in range(len(nums)):if nums[i] > 0:breakif i > 0 and nums[i] == nums[i-1]:continuel = i+1r = len(nums) - 1while l < r:if nums[i] + nums[l] + nums[r] < 0:l+=1elif nums[i] + nums[l] + nums[r] > 0:r-=1else:result.append([nums[i], nums[l], nums[r]])l+=1r-=1while nums[l] == nums[l-1] and l < r:l+=1return result

这篇关于【LeetCode最详尽解答】15-三数之和 3sum的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

Adblock Plus官方规则Easylist China说明与反馈贴(2015.12.15)

-------------------------------特别说明--------------------------------------- 视频广告问题:因Adblock Plus的局限,存在以下现象,优酷、搜狐、17173黑屏并倒数;乐视、爱奇艺播放广告。因为这些视频网站的Flash播放器被植入了检测代码,而Adblock Plus无法修改播放器。 如需同时使用ads