目录
18 四数之和
题目描述:
给你一个由 n
个整数组成的数组 nums
,和一个目标值 target
。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]]
(若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a
、b
、c
和d
互不相同nums[a] + nums[b] + nums[c] + nums[d] == target
题解:排列➕双指针(借助三数之和)
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
l = len(nums)
ans = []
#for i in range(l-2):不对
for i in range(l-3):
if i > 0 and nums[i] == nums[i-1]:
continue
if nums[i] > target / 4:
break
cur_target = target - nums[i]
#sub_nums = nums[i:] 不对
sub_nums = nums[i + 1:]
for sub_ans in self.threeSum(sub_nums, cur_target, l - i - 1):
#不能这样写
# cur_ans = sub_ans.append(nums[i])
cur_ans = [nums[i]] + sub_ans
ans.append(cur_ans)
return ans
def threeSum(self, nums, target, l):
ans = []
for i in range(l-2):
#注意
if i > 0 and nums[i] == nums[i-1]:
continue
slow = i + 1
fast = l - 1
#注意
while slow < fast:
cur_sum = nums[i] + nums[slow] + nums[fast]
if cur_sum < target:
slow += 1
elif cur_sum > target:
fast -= 1
else:
ans.append([nums[i], nums[slow], nums[fast]])
while slow < fast and nums[slow] == nums[slow+1]:
slow += 1
while slow < fast and nums[fast] == nums[fast-1]:
fast -= 1
slow += 1
fast -= 1
return ans
454 四数相加2
题目描述:
给你四个整数数组 nums1
、nums2
、nums3
和 nums4
,数组长度都是 n
,请你计算有多少个元组 (i, j, k, l)
能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
题解一:
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
sum12_map = {}
ans = 0
for i, a in enumerate(nums1):
for j, b in enumerate(nums2):
cur_sum = str(a + b)
if cur_sum in sum12_map.keys():
sum12_map[cur_sum] += 1
else:
sum12_map[cur_sum] = 1
for i, a in enumerate(nums3):
for j, b in enumerate(nums4):
cur_sum = str(- (a + b))
if cur_sum in sum12_map.keys():
ans += sum12_map[cur_sum]
return ans
题解二:collections.Counter
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
#sum12_map = {}
ans = 0
# for i, a in enumerate(nums1):
# for j, b in enumerate(nums2):
# cur_sum = str(a + b)
# if cur_sum in sum12_map.keys():
# sum12_map[cur_sum] += 1
# else:
# sum12_map[cur_sum] = 1
sum12_map = collections.Counter(u + v for u in nums1 for v in nums2)
for i, a in enumerate(nums3):
for j, b in enumerate(nums4):
cur_sum = - (a + b)
# cur_sum = str(- (a + b))
# if cur_sum in sum12_map.keys():
if cur_sum in sum12_map:
ans += sum12_map[cur_sum]
return ans
383 赎金信
题目描述:
给你两个字符串:ransomNote
和 magazine
,判断 ransomNote
能不能由 magazine
里面的字符构成。
如果可以,返回 true
;否则返回 false
。
magazine
中的每个字符只能在 ransomNote
中使用一次。
题解一:
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
magazine_dict = {}
for _, e in enumerate(magazine):
if e in magazine_dict.keys():
magazine_dict[e] += 1
else:
magazine_dict[e] = 1
for i, e in enumerate(ransomNote):
if e not in magazine:
return False
elif magazine_dict[e] == 0:
return False
else:
magazine_dict[e] -= 1
return True
题解二:collections.Counter
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
if len(ransomNote) > len(magazine):
return False
# 在 collections.Counter 中,相减运算指的是两个计数器对象之间的减法操作。这个操作会计算两个计数器中各个元素的差异。
# 具体来说,假设有两个 Counter 对象 counter1 和 counter2,它们分别表示不同元素的计数情况。当执行 counter1 - counter2 时,将对两个计数器对象进行减法运算,得到一个新的 Counter 对象。
# 减法运算会对每个元素的计数进行操作:
# 如果某个元素在 counter1 中的计数大于等于在 counter2 中的计数,则在结果 Counter 对象中该元素的计数为两者之差。
# 如果某个元素在 counter1 中的计数小于在 counter2 中的计数,或者该元素在 counter1 中不存在,则在结果 Counter 对象中该元素的计数为 0。
return not collections.Counter(ransomNote) - collections.Counter(magazine)