leetcode 3Sum
2015-11-30 12:26
281 查看
https://leetcode.com/problems/3sum/
sort之后就有大小关系,就可能只需要遍历一部分或者可以减枝
另一个sort的原因就是题目要求Elements in a triplet (a,b,c) must be in non-descending order.
参考/article/4982505.html
解题思路:1,先将数组排序。
2,排序后,可以按照TwoSum的思路来解题。怎么解呢?可以将num[i]的相反数即-num[i]作为target,然后从i+1到len(num)-1的数组元素中寻找两个数使它们的和为-num[i]就可以了。下标i的范围是从0到len(num)-3。
3,这个过程要注意去重。就是说j指向的数可能有很多个,k指向的数也有很多个
4,时间复杂度为O(N^2)。
当num[left] + num[right] < -num[i]时,我们可以不用break
参考http://codesays.com/2014/solution-to-3sum-by-leetcode/ 的code
这里要注意i,j,k都要去重复。
my code
Note1
这里可以利用two sum binary search的方法,对于每一个i,利用j, k two pointers 去找sum 等于-nums[i].Note2
如果是O(N^2)的遍历,要思考是否可以sort一下,然后用two pointers. 因为最后只返回不重复的值,例如,如果a<ba, 遍历a的时候会找到(a,b),遍历b的时候会找到a,所以只要sort一下,遍历到a的时候,只需要遍历a以后的值就行。这样没有降低复杂度,依然还是N^2的方法。但是可以有效的去重复,并且还要注意i,j,k 在遍历的时候对应的元素也要去重复。sort之后就有大小关系,就可能只需要遍历一部分或者可以减枝
另一个sort的原因就是题目要求Elements in a triplet (a,b,c) must be in non-descending order.
参考/article/4982505.html
解题思路:1,先将数组排序。
2,排序后,可以按照TwoSum的思路来解题。怎么解呢?可以将num[i]的相反数即-num[i]作为target,然后从i+1到len(num)-1的数组元素中寻找两个数使它们的和为-num[i]就可以了。下标i的范围是从0到len(num)-3。
3,这个过程要注意去重。就是说j指向的数可能有很多个,k指向的数也有很多个
4,时间复杂度为O(N^2)。
class Solution: # @return a list of lists of length 3, [[val1,val2,val3]] def threeSum(self, num): num.sort() res = [] for i in range(len(num)-2): if i == 0 or num[i] > num[i-1]:#这里因为num已经sort了,所以这里仅仅是说i如果指向了与上一个元素相同的数,那么就continue。我们只考虑第一个。sort了之后也会有相同的值,e.g.{1,1,1,2,2},只考虑第一个1,第一个2 left = i + 1; right = len(num) - 1 while left < right: if num[left] + num[right] == -num[i]: res.append([num[i], num[left], num[right]]) left += 1; right -= 1 while left < right and num[left] == num[left-1]: left +=1#去掉重复值 while left < right and num[right] == num[right+1]: right -= 1 elif num[left] + num[right] < -num[i]:#如果小于target,那么就要增加num[left] + num[right],因为sorted,所以left向右移就行。 while left < right:#这里也是去掉重复值,可以改造不用break left += 1 if num[left] > num[left-1]: break else: while left < right: right -= 1 if num[right] < num[right+1]: break return res
当num[left] + num[right] < -num[i]时,我们可以不用break
while left < right: if num[left] + num[right] == -num[i]: res.append([num[i], num[left], num[right]]) left += 1; right -= 1 while left < right and num[left] == num[left-1]: left +=1#去掉重复值 while left < right and num[right] == num[right+1]: right -= 1 elif num[left] + num[right] < -num[i]:#如果小于target,那么就要增加num[left] + num[right],因为sorted,所以left向右移就行。 #print (left,right) while left < right and num[left + 1] == num[left]: left += 1 left += 1 else: while left < right and num[right - 1] == num[right]: right -= 1 right -= 1
参考http://codesays.com/2014/solution-to-3sum-by-leetcode/ 的code
这里要注意i,j,k都要去重复。
my code
class Solution(object): def threeSum(self, nums): """ :type nums: List[int] :rtype: List[List[int]] """ if len(nums) < 3: return [] nums.sort() #after sort(), we just need two pointers to scan res = [] i = 0 while i < len(nums) - 2: j = i + 1 k = len(nums) - 1 while j < k: if nums[i] + nums[j] + nums[j] > 0 or nums[i] + nums[k] + nums[k] < 0: break if nums[i] + nums[j] + nums[k] == 0: res.append([nums[i], nums[j], nums[k]]) j += 1 while j < k and nums[j] == nums[j - 1]: j += 1 k -= 1 while k > j and nums[k] == nums[k + 1]: k -= 1 elif nums[i] + nums[j] + nums[k] < 0: j += 1 while j < k and nums[j] == nums[j-1]: j += 1 else: # Skip duplicate num[k+1] k -= 1 while k > j and nums[k] == nums[k+1]: k -= 1 i += 1 while i < len(nums) - 2 and nums[i] == nums[i - 1]: i += 1 return res
相关文章推荐
- Hibernate主键
- 判断App整体处于前台还是后台
- 设计模式之禅-学习笔记 之 第一章:单一职责原则
- python处理文本又一坑--又是编码
- UITextField的使用
- Bugtags 使用技巧之 setUserData
- hdu5569 matrix
- UESTC 58 任意阶矩阵的乘法 虽然简单但优化还是要思考一下的 而且也使自己意识到了原来没有注意的问题
- csky elf文件 查看符号表
- 如何选择前端框架:ANGULAR VS EMBER VS REACT
- ios9 http请求不通。修改plist文件也不行的状况
- 微信企业号如何置顶?
- 【国外戒色经验第十七期】:国外戒友近400天不撸的秘密
- JAVA基础(2)
- AFNetworking 3.0.4
- [leetcode] 91. Decode Ways 解题报告
- 有关Hibernate映射关系 no session or session was closed问题解绝方法
- shell脚本中相关技巧
- div+ajax 实现网页框架布局
- Spring的事务管理