栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

LeetCode 三数之和

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

LeetCode 三数之和

三数之和

题目来源:https://leetcode-cn.com/problems/3sum

题目

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

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

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
解题思路
  1. 数组排序 + 双指针;
  2. 首先摘取特殊情况,直接处理。数组 nums 为空(或 None)或者 nums 长度小于 3 时,直接返回空列表;
  3. 排除特殊情况后,先对数组进行排序;
  4. 对数组进行遍历,判断三数之和是否满足为 0:
    1. 先固定一个值,即是 nums[i];
    2. 如果 nums[i] 大于 0,因为数组已经经过排序,这样表示 nums[i] 与后面任意两值之和不可能等于 0,直接跳出循环;
    3. 对数值进行去重,避免结果重复,重复的条件为当前的数值与前面的数值相等,即是 nums[i] == nums[i-1],符合条件直接跳过;
    4. 定义左右指针 L 和 R,固定 nums[i] 的值后,当 L 小于 R 时,在两个指针区间找出与 nums[i] 之和为 0 的两值;
    5. 当 three_num==0 时,将三个数值添加到返回列表,同时继续查找符合条件的数值。若是 nums[L]==nums[L+1],表示重复,跳过,即是让 L+= 1 往右移动;若是 nums[R]==nums[R-1],同样表示重复,跳过,即是让 R-=1 往左移动;
    6. 当 three_num < 0 时,表示左边指针的值过小,左指针往右移动;
    7. 当 three_num > 0 时,表示右边指针的值过大,右指针往左移动。
    8. 时间复杂度:O(n2)O(n^2)O(n2)。数组排序:O(nlogn)O(nlogn)O(nlogn);固定 nums[i] 值:O(n)O(n)O(n);双指针遍历:O(n)O(n)O(n);最终时间复杂度为:O(n)∗O(n)+O(nlogn)O(n)*O(n)+O(nlogn)O(n)∗O(n)+O(nlogn),为 O(n2)O(n^2)O(n2)
图解

代码实现
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
 '''返回三个数为 0 的不重复三元组集

 Args:
     nums: 整数数组
 
 Returns:
     返回三元组集,不包含重复的三元组
 '''
 # 初始化返回数组
 res = []
 nums_len = len(nums)
 # 特殊情况直接返回空列表
 # nums 为空时,长度小于 3 时
 if not nums or nums_len < 3:
     return res
 # 先对数组排序
 nums.sort()
 for i in range(nums_len): # i 对应的值表固定值
     # 因为数组已经排序,如果 nums[i] > 0,这个数值与后面的数值之和一定会大于 0,直接跳出循环
     if nums[i] > 0:
  break
     # 如果 nums[i] == nums[i-1] 表示已经重复
     # 跳过至重复值最后 1 位,这样能够避免重复的三元组添加到返回列表
     if i > 0 and nums[i] == nums[i - 1]:
  continue
     # 左右指针,一个紧跟固定值后面,一个为末尾值
     L = i + 1
     R = nums_len - 1
     while L < R:
  # 计算三数之和
  three_sum = nums[i] + nums[L] + nums[R]
  if three_sum == 0: # 当三数之和等于 0,改变指针 L 跟 R 的位置
      res.append([nums[i], nums[L], nums[R]])
      # 表示去重
      while (L < R) and (nums[L] == nums[L + 1]):
   L += 1
      # 去重
      while (L < R) and (nums[R] == nums[R - 1]):
   R -= 1
      L += 1
      R -= 1
  elif three_sum < 0: # 三数之和小于 0,表示指针 L 对应的数值过小,往右边移动
      L += 1
  elif three_sum > 0: # 三数之和大于 0,表示指针 R 对应的数值过大,往左边移动
      R -= 1
 return res
实现结果


以上就是运用数组排序、双指针解决《三数之和》问题的主要内容


欢迎关注『书所集录』公众号
> 欢迎关注微信公众号《书所集录》
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号