欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

python刷题--N数之和问题(双指针+剪枝)

时间:2023-05-31

1.两数之和(双指针)

这题前面已经做过,当时是用哈希表做的,时间复杂度为N

但如果换一种思路,用今天学的双指针来做,虽然在时间复杂度上不降反增(因为排序的复杂度为NlogN)但理解起来十分简单清晰。(注:对于三数四数N数之和问题来说,双指针算法相当于将最内部的两层循环优化成一层。)

思路:即先排序,得到一个有序的列表,一个指针指向列表开头,一个指向末尾,对于每一个状态而言,如果大于目标值则让右指针左移,小于目标值则让左指针右移。该方法适用于求无重复的解。

个人题解:

# 注释1class Solution: def twoSum(self, nums: List[int], target: int): res = [] i, j = 0, len(nums)-1 nums.sort() for i in range(len(nums)): if i > 0 and nums[i-1] == nums[i]: continue while i < j and nums[i] + nums[j] > target: j -= 1 if i == j: # 注释2,3 break if nums[i] + nums[j] == target: res.append([nums[i], nums[j]]) return res

注释1:# 注意这不是题目:两数之和的解,这代码的条件是跟后面的三数之和四数之和相同时才能成立(必须要求只返回目标值而不是返回索引)

注释2:# 能导致i=j的只有两种情况。一:由内层循环得到,那么当前状态的前一个状态nums[i]+nums[j] 是大于target的,此时期待减少两个数的和,但是控制减小的指针j已经无法向左移,所以循环结束二:由外层循环得到,那么当前状态的前一个状态nums[i]+nums[j]是小于target的,此时期待增大两个数的和,但是控制增大的指针i已经无法向右移,循环结束

注释3:在上述情况发生时(期待增大的两个数之和,但是控制增大的指针i无法向右移)。那么可不可以让j往右移动(回头)呢?

答:是不行的。看上去j向右移动,和这个状态的i是一组全新的i,j组合,是没有遍历过的,那为什么不能这样呢?

我们来假设这样的情况成立。。假设在移动之前i和j的位置分别为i0和j0那么j0向右移动后移到某个j1的位置,此时nums[i0]+nums[j1]的值是大于等于0(或者目标值的),假设i在最开始的位置是i1,那么当j第一次运动到j1的位置时,i在i1的位置,这个时候的nums[i1]+nums[j1]是小于nums[i0]+nums[j1]的,而j1运动到j0是为了使整体值减小,那么第一次的nums[i1]+nums[j1]一定就是大于0,所以对比两个状态,i1和j1这个状态下已经大于0,那么就不会再让i1增大得到i0,所以与我们一开始设定好的值大就减小,值小就增大的思想不符,假设不成立。

2.三数之和

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

官方题解:

class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: n = len(nums) nums.sort() ans = list() # 枚举 a for first in range(n): # 需要和上一次枚举的数不相同 if first > 0 and nums[first] == nums[first - 1]: continue # c 对应的指针初始指向数组的最右端 third = n - 1 target = -nums[first] # 枚举 b for second in range(first + 1, n): # 需要和上一次枚举的数不相同 if second > first + 1 and nums[second] == nums[second - 1]: continue # 需要保证 b 的指针在 c 的指针的左侧 while second < third and nums[second] + nums[third] > target: third -= 1 # 如果指针重合,随着 b 后续的增加 # 就不会有满足 a+b+c=0 并且 b

思想一样,就是在外层再套一个循环。

3.四数之和

题目:https://leetcode-cn.com/problems/4sum/

整体思路一样,题解可以看看,多了个剪枝操作(通过判断情况筛选掉不必要的循环)

官方题解:

https://leetcode-cn.com/problems/4sum/solution/si-shu-zhi-he-by-leetcode-solution/https://leetcode-cn.com/problems/4sum/solution/si-shu-zhi-he-by-leetcode-solution/

4.N数之和 

道理一样,就是在外层套循环。然后将最内的两层循环改为双指针操作。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。