python--三数值之和
记录一下,用以自学
题目:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
为了减低时间复杂度,我使出了洪荒之力,模仿两数之和,最后修改的代码为:
from typing import List class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: # 试试用第三个数找前面的数 s=[] dict={} for i in range(len(nums)): otherNum=-nums[i] k=dict.get(otherNum) if k!=None: for j in k: s0=sorted([nums[i],j[0],j[1]]) if s0 not in s: s.append(s0) # 记录下这个数的所有组合 for g in range(i): addedNum=nums[g]+nums[i] kg=dict.get(addedNum) if kg == None: dict[addedNum]=[[nums[g],nums[i]]] else: dict[addedNum].append([nums[g],nums[i]]) return s
初略计算一下时间复杂度,如果不算
kg=dict.get(addedNum)
的时间复杂度是O(n2),但是应该是要算的,所以时间复杂度应该是O(n3),超时,呜呜呜呜,想不到更好的办法了
看解答:
答案的思路就是先排序,然后以类似双指针的方式,先遍历first,计算他需要的target,然后以双指针的方式去寻找加起来等于-target的second 和third
second从first+1开始,third从n-1开始,加起来比目标数大的话,third-1,加起来比目标数小的话,second+1,一旦second==third,本轮结束
题目要求不能重复输出,所以需要添加很多限制条件:
可以在选择的时候,筛选,但这样会比较慢,根据解答的思路写出来是这样子的
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: s=[] nums.sort() n=len(nums) for first in range(n): target=-nums[first] second=first+1 third = n - 1 while(second<third): t=nums[second]+nums[third] if t==target : k=[nums[first],nums[second],nums[third]] if k not in s: s.append(k) second+=1 third-=1 elif(t<target): second+=1 else: third-=1 return s
可以通过判断second和third的关系来限制,增加了两个限制条件,两个条件是抄解答的,不是很理解
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: s=[] nums.sort() n=len(nums) for first in range(n): #为了防止重复 if first > 0 and nums[first] == nums[first - 1]: continue target=-nums[first] second=first+1 third = n - 1 while(second<third): #为了防止重复 if nums[second]==nums[second-1] and second-1!=first: second+=1 continue t=nums[second]+nums[third] if t==target : s.append([nums[first],nums[second],nums[third]]) second+=1 third-=1 elif(t<target): second+=1 else: third-=1 return s
双指针的思路确实很有用,上一道题计算水的容量也用到了,那个时候也没想起来,顺便记一下:
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
看解答后的代码
class Solution: def maxArea(self, height: List[int]) -> int: maxV = 0 i,j=0,len(height)-1 while(i!=j): li = height[i] lj = height[j] v=(j-i)*min(li,lj) if(maxV<v): maxV=v if(li<=lj): i+=1 else: j-=1 return maxV
双指针利用的是排序后的数据大小关系,容器的那道题利用的是x轴距离相差越大越好的特点。

浙公网安备 33010602011771号