最近在在刷 LeetCode,已经刷到 15 题了,但是在 15 题这卡住了,特来请教。以下是我的代码
class Solution: def threeSum(self, nums): negative = [] negative_again = [] positive = [] positive_again= [] zero = [] answer = [] m, n = 0, 0 for value in nums: if value < 0: if -value not in negative: negative.insert(0, -value) elif -value not in negative_again: negative_again.append(-value) elif value > 0: if value not in positive: positive.append(value) elif value not in positive_again: positive_again.append(value) else: zero.append(value) positive.sort() negative.sort() if len(zero) > 2: answer.append([0, 0, 0]) if len(positive) == 0 or len(negative) ==0: return answer for i in negative: # [i, 0, -i] # 第一个 for n = 1 + n if i > positive[-1]: break for j in negative[n:]: # [i, j, -i-j] ij = i + j #print(i, i, ij) if ij > positive[-1]: break if ij in positive: pre_answer = [-j, -i, ij] answer.append(pre_answer) for i in positive: # 第二个 for m = m + 1 if i > negative[-1]: break for j in positive[m:]: ij = i + j if ij > negative[-1]: break if ij in negative: pre_answer = [i, j, -ij] answer.append(pre_answer) if len(zero) > 0: for i in positive: if i in negative: answer.append([-i, 0, i]) for i in negative_again: if (i + i) in positive: pre_answer = [-i, -i, i+i] answer.append(pre_answer) for i in positive_again: if (i + i) in negative: pre_answer = [ -i-i, i, i] answer.append(pre_answer) return answer
这里是第一名的代码(我借鉴他的思路写的,但是速度差了 100 倍)
class Solution: def threeSum(self, nums): """ :type nums: List[int] :rtype: List[List[int]] """ out = [] zero = 0 positive, negative = {}, {} p_max = 0 n_min = 0 import itertools if not nums: return out for i in nums: if i > 0: positive[i] = positive.get(i, 0) + 1 if i > p_max: p_max = i elif i < 0: negative[i] = negative.get(i, 0) + 1 if i < n_min: n_min = i else: zero += 1 if len(positive) == 0 or len(negative) == 0: if zero > 2: out.append([0, 0, 0]) return out p = sorted(positive.keys()) for i in range(len(p)): # 第一个 for if p[i] > -n_min: break for j in range(i+1, len(p)): s = p[i]+p[j] if s > -n_min: break if -s in negative: out.append([p[i], p[j], -s]) if positive[p[i]] >= 2: if -(p[i]*2) in negative: out.append([p[i], p[i], -(p[i]*2)]) n = sorted([-k for k in negative]) for i in range(len(n)): # 第二个 for if n[i] > p_max: break for j in range(i + 1, len(n)): s = n[i] + n[j] if s > p_max: break if s in positive: out.append([-n[i], -n[j], s]) if negative[-n[i]] >= 2: if (n[i]*2) in positive: out.append([-n[i], -n[i], (n[i]*2)]) if zero > 0: for i in positive: if -i in negative: out.append([i,0,-i]) if zero > 2: out.append([0, 0, 0]) return out
我导入了 timeit,计算了一下时间,差别在 for 循环的块里(就是我注释的两个 for 循环),排查了两晚上,也没找到答案。
1 getlost OP https://leetcode-cn.com/problems/3sum/submissions/ 这是 LeetCode 题目。 |
![]() | 2 wallriding 2019-03-10 21:43:24 +08:00 这题需要写这么长吗? |
3 getlost OP @wallriding 刚开始练习,还需要努力学习 |
![]() | 4 wallriding 2019-03-10 22:18:06 +08:00 @getlost 你直接看 discussion 里最高票帖子呀 |
5 getlost OP @wallriding 第二段代码是耗时最短的解法,我参考他的解法来做了一次,但是存在疑问,因为用了同样的逻辑,耗时却差了 100 倍,我很疑惑,不知道哪里理解错了。 |
6 Gakho 2019-03-11 10:31:10 +08:00 试过 copy 第一名的解法直接提交,时间也会出现差了一半以上,说实话对于这个时间我大多数抱着看看就好的心态 |
![]() | 8 hanbaobao2005 2019-03-11 17:37:17 +08:00 insert 的效率很差,不建议使用 |
9 getlost OP @hanbaobao2005 学习了,之前没了解过。我导入 timeit 模块,发现我的两个 for 循环占用的时间占总时间的 99%,不太明白为什么? |
![]() | 10 hanbaobao2005 2019-03-12 07:20:34 +08:00 @getlost 替换 insert 试过了么? |