python - Leetcode 题 '3Sum' 算法超过时限,寻求改进
问题描述
给定一个由 n 个整数组成的数组 nums,在 nums 中是否存在元素 a、b、c 使得 a + b + c = 0?在数组中找到所有唯一的三元组,其总和为零。
class Solution:
def threeSum(self, nums):
data = []
i = j = k =0
length = len(nums)
for i in range(length):
for j in range(length):
if j == i:
continue
for k in range(length):
if k == j or k == i:
continue
sorted_num = sorted([nums[i],nums[j],nums[k]])
if nums[i]+nums[j]+nums[k] == 0 and sorted_num not in data:
data.append(sorted_num)
return data
我的解决方案运行良好,但似乎它可能太慢了。有没有办法在不显着改变代码的情况下改进我的代码?
解决方案
这是一个具有一些优化技巧的 O(n^2) 解决方案:
import itertools
class Solution:
def findsum(self, lookup: dict, target: int):
for u in lookup:
v = target - u
# reduce duplication, we may enforce v <= u
try:
m = lookup[v]
if u != v or m > 1:
yield u, v
except KeyError:
pass
def threeSum(self, nums: List[int]) -> List[List[int]]:
lookup = {}
triplets = set()
for x in nums:
for y, z in self.findsum(lookup, -x):
triplets.add(tuple(sorted([x, y, z])))
lookup[x] = lookup.get(x, 0) + 1
return [list(triplet) for triplet in triplets]
首先,您需要一个哈希查找来将您的 O(n^3) 算法减少到 O(n^2)。这就是整个想法,其余的都是微优化:
- 查找表是与对数组的扫描一起构建的,因此它是一次性的
- 以前见过的唯一项目的查找表索引,因此它可以有效地处理重复项,并且通过使用它,我们将二级循环的迭代次数保持在最低限度
推荐阅读
- java - 给定一个全为 0 的二进制字符串,将其隐藏在目标字符串中
- java - 在 java 中,System.out.println 方法如何在静态和非静态上下文中工作?
- c - 为什么使用 \"%s\" 时 sprintf 不起作用?
- android - 当应用程序来自后台时始终触发观察者
- angular - 嵌套子项的 ngxs 状态更改
- node.js - 通过 SmartAdmin 项目调试 Gulp Build 失败
- c# - 无法通过 C# 启动服务
- android - 可以在房间数据库迁移的单个语句中添加多个新列吗?
- django - 如何实现删除查询的搜索栏按钮?Django环境)
- algorithm - 分配任务的动态规划算法