四数之和II
力扣
思路:
这道题我们可以拆分为两个部分来做,首先计算前两个数组元素的和并且统计这个组合出现的次数,然后用0减掉后两个数组。
如果发现0减去后两个数组已经出现在我们之前记录出现次数的map中了,那么就可以说他们是一个四元组组合,并且这里加的次数 就应该是我们之前记录过的次数而不是+1
代码:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
map = {}
count=0
for i in nums1:
for j in nums2:
if i + j in map:
map[i+j]+=1
else:
map[i+j] = 1
for x in nums3:
for y in nums4:
if 0-(x+y) in map:
count+=map.get(0-(x+y))
return count
383赎金信
力扣
思路:这道题 可谓是一个完全自己写出来的题目,其他的多多少少看了些提示。
这里我分别对两个字符做了字母出现次数的统计。并且分别用哈希表存起来
然后重新遍历ransomnote。 如果说这里面的元素在第二个hash表中出现过,那么就减去对应出现过的次数。直到最后 记录ransomnote的哈希表的key值全部为0 .可以发现最后我是用的>0来判断的,如果说它大于0.说明第二个字符中的字母少了,也就是符合我们的题目 不能构成了。
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
hashmap ={}
hashmap1 = {}
if len(magazine) < len(ransomNote):
return False
for i in range(len(ransomNote)):
if ransomNote[i] not in hashmap:
hashmap[ransomNote[i]] = 1
else:
hashmap[ransomNote[i]]+=1
for j in range(len(magazine)):
if magazine[j] not in hashmap1:
hashmap1[magazine[j]] = 1
else:
hashmap1[magazine[j]]+=1
for k,v in hashmap.items():
if k in hashmap1:
hashmap[k]-=hashmap1[k]
for k1,v1 in hashmap.items():
if v1>0:
return False
return True
三数之和
力扣
思路:
这道题目的难点在于 答案元组不能重复 并不是代表元组内的元素不能重复
首先对数组进行排序,如果说第一个数字都大于0的,那么和后面的数字相加也不可能等于0,所以可以直接返回答案集合。
其次,这里设置一个i,left,right. i是遍历元组内的元素,left是i+1,right是数组内的最后一个元素。
刚开始遍历的时候用value = nums[i] + nums[left] + nums[right] ,判断是否大于0。 如果大于0,那就说明left应该往后移动一位,如果大于0,说明right应该往前走一位。 如果等于0 ,就可以加入到答案数组中。然后分别对left和right元素进行去重
代码:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
result = []
for i in range(len(nums)):
if nums[i] >0:
return result
if i > 0 and nums[i] == nums[i - 1]:
continue
left = i+1
right = len(nums)-1
while right>left:
value = nums[i] + nums[left] + nums[right]
if value>0:
right-=1
elif value <0:
left+=1
else:
result.append([nums[i],nums[left],nums[right]])
while right>left and nums[right]==nums[right-1]:
right-=1
while right>left and nums[left]==nums[left+1]:
left+=1
right-=1
left+=1
return result
四数之和
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
result = []
nums.sort()
for i in range(len(nums)):
if nums[i] > target and i>=0 and target>0:
break
if i>0 and nums[i] ==nums[i-1]:
continue
for k in range(i+1,len(nums)):
if nums[i] + nums[k] >target and nums[k] + nums[i] >=0:
break
if k>i+1 and nums[k] ==nums[k-1]:
continue
left = k+1
right = len(nums)-1
while left<right:
value = nums[i] + nums[k] + nums[left] + nums[right]
if value >target:
right-=1
elif value <target:
left+=1
else:
result.append([nums[i],nums[k],nums[left],nums[right]])
while left < right and nums[left]==nums[left+1]:
left+=1
while left <right and nums[right] ==nums[right-1]:
right-=1
left+=1
right-=1
return result
思路:
这道题和上面不同的是,我们不能通过一开始判断第一个元素>target就直接返回,因为上一道题目的target是一个定值,但是这道题中是一个任意值,我们可以通过后面元素相加而得到。除非是说当前元素大于target 并且target>0,那么我们可以进行break 然后继续判断后面的元素。
其他地方 和上一道题目 基本都一样
代码: