def(self, nums): nums.sort() l, r = 0, len(nums) - 1 res = [] for i in range(len(nums) - 2): if i > 0and nums[i] == nums[i - 1]: continue l, r = i + 1, len(nums) - 1 while l < r: s = nums[i] + nums[l] + nums[r] if s < 0: l += 1 elif s > 0: r -= 1 else: res.append([nums[i], nums[l], nums[r]]) l += 1 r -= 1 while l < r and nums[l] == nums[l - 1]: l += 1 while l < r and nums[r] == nums[r + 1]: r -= 1 return res
defthreeSumClosest(self, nums: List[int], target: int) -> int: nums.sort() res = float('inf') for i in range(len(nums) - 2): l, r = i + 1, len(nums) - 1 while l < r: s = nums[i] + nums[l] + nums[r] if abs(s - target) < abs(res - target): res = s if s > target: r -= 1 while l < r and nums[r] == nums[r + 1]: r -= 1 elif s < target: l += 1 while l < r and nums[l] == nums[l - 1]: l += 1 else: return target return res
If sum of numbers at i, l, r is smaller than target, then the sum would also smaller than the target if r keeps moving to l. Thus cnt += r - l
1 2 3 4 5 6 7 8 9 10 11 12 13
defthreeSumSmaller(self, nums: List[int], target: int) -> int: nums.sort() cnt = 0 for i in range(len(nums) - 2): l, r = i + 1, len(nums) - 1 while l < r: s = nums[i] + nums[l] + nums[r] if s >= target: r -= 1 elif s < target: cnt += r - l l += 1 return cnt
deffourSum(self, nums: List[int], target: int) -> List[List[int]]: res = [] nums.sort() def(arr, tar): res = [] for i in range(len(arr) - 2): if i > 0and arr[i] == arr[i - 1]: continue l, r = i + 1, len(arr) - 1 while l < r: s = arr[i] + arr[l] + arr[r] if s < tar: l += 1 elif s > tar: r -= 1 else: res.append([arr[i], arr[l], arr[r]]) l += 1 r -= 1 while l < r and arr[l] == arr[l - 1]: l += 1 while l < r and arr[r] == arr[r + 1]: r -= 1 return res i = 0 while i < len(nums) - 3: threeRes = threeSum(nums[i + 1:], target - nums[i]) for r in threeRes: res.append([nums[i]] + r) i += 1 while0 < i < len(nums) - 3and nums[i] == nums[i - 1]: i += 1 return res
Count the number of sums of all the combinations in A and B.
Calculate sums in C and D and see if there’s any match in counter[-c-d]
1 2 3
deffourSumCount(self, A: List[int], B: List[int], C: List[int], D: List[int]) -> int: count = collections.Counter([a + b for a in A for b in B]) return sum([count[-c-d] for c in C for d in D])
When s == target, we have two situations to consider: 1). The left and right number are the same 2). The left and right number are different
When they are different, we need to count both left and right numbers and multiply them (Note that we need to use l + 1 < r rather than l < r to count all the numbers)
defthreeSumMulti(self, nums, target): cnt = 0 MOD = 10 ** 9 + 7 nums.sort() for i in range(len(nums) - 2): l, r = i + 1, len(nums) - 1 while l < r: s = nums[i] + nums[l] + nums[r] if s > target: r -= 1 elif s < target: l += 1 else: if nums[l] != nums[r]: left = right = 1 while l + 1 < r and nums[l] == nums[l + 1]: # l + 1 < r l += 1 left += 1 while l + 1 < r and nums[r] == nums[r - 1]: r -= 1 right += 1 cnt += left * right l += 1 r -= 1 else: cnt += (r - l + 1) * (r - l) / 2 break return cnt % MOD
When starting searching for the next round, we don’t need to reset r to j + 1, instead, we can directly start from where we stopped in the last round.
Since all the edges are triangle edge, don’t forget about to check if nums[i] == 0
1 2 3 4 5 6 7 8 9 10 11 12
deftriangleNumber(self, nums: List[int]) -> int: cnt = 0 nums.sort() for i in range(len(nums) - 2): r = i + 2# [1] for j in range(i + 1, len(nums) - 1): if nums[i] == 0: # [2] continue while r < len(nums) and nums[i] + nums[j] > nums[r]: r += 1 cnt += r - j - 1 return cnt
Remember to add what’s left in list B into list A.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
defmerge(self, A: List[int], m: int, B: List[int], n: int) -> None: """ Do not return anything, modify nums1 in-place instead. """ cur = m + n - 1 a = m - 1 b = n - 1 while cur >= 0and a >= 0and b >= 0: if A[a] > B[b]: A[cur] = A[a] a -= 1 else: A[cur] = B[b] b -= 1 cur -= 1 # Add missing elements from B A[:b + 1] = B[:b + 1]
近期评论