classSolution: defthreeSumClosest(self, nums: List[int], target: int) -> int: # 时间:排序O nlogn,过程 n方,总共算n方;空间 O 1 nums.sort() n = len(nums) ans = 1000000 for i inrange(n-2): if i>0and nums[i]==nums[i-1]: #跳过已经算过的 continue s = nums[i]+nums[i+1]+nums[i+2]# 最小的情况也比target大,其他情况只会更大,所以就只考虑这一种情况 if s > target: ifabs(ans - target) > abs(s - target): ans = s break# 由于i往后也只会更大,所以干脆终止 s = nums[i]+nums[-2]+nums[-1]# 最大的情况也比target小,其他情况只会更小,所以就只考虑这一种情况 if s < target: ifabs(ans - target) > abs(s - target): ans = s continue
j = i+1 k = n-1
while j < k: s = nums[i]+nums[j]+nums[k] ifabs(ans - target) > abs(s - target): ans = s if s == target: break elif s > target: k -= 1 else: j += 1 return ans
classSolution: deffourSum(self, nums: List[int], target: int) -> List[List[int]]: # 时间复杂度,排序 nlogn,过程是n的三次方,所以就是三次方;空间复杂度O 1 ans = [] nums.sort() n = len(nums) for i inrange(n-3): if i > 0and nums[i] == nums[i-1]: continue
sub_target = target - nums[i] for j inrange(i+1, n-2): if j > i+1and nums[j] == nums[j-1]: continue # 让极大和极小的情况节省时间 if nums[j] + nums[-2] + nums[-1] < sub_target: continue if nums[j] + nums[j+1] + nums[j+2] > sub_target: break
p, q = j+1, n-1 while p < q: s = nums[j] + nums[p] + nums[q] if s == sub_target: ans.append([nums[i], nums[j], nums[p], nums[q]]) p += 1 while p<q and nums[p] == nums[p-1]: p += 1 q -= 1 while p<q and nums[q] == nums[q+1]: q -= 1 elif s > sub_target: q -= 1 else: p += 1 return ans
classSolution: deftriangleNumber(self, nums: List[int]) -> int: ans = 0 nums.sort() n = len(nums) for i inrange(n-1, 1, -1): # i足够小,连所有最小的两个值都更大,剩下随便三个数都能是三角形 if nums[0]+nums[1] > nums[i]: ans += (i+1)*i*(i-1)//6 break # i太大了,这个循环内不可能有满足的 if nums[i-2]+nums[i-1]<=nums[i]: continue