454.四数相加II
题目链接454. 四数相加 II - 力扣(LeetCode)
刚开始看完题一点思路都没有
思路
假设有数组A,B,C,D,取A,B中数a,b,遍历得到a+b,用map存下a+b的值,并记录每种值出现的次数。
取C,D中数c,d,遍历得到c+d,查找a+b=-(c+d)是否在map中出现过
如果在map中出现了,那count需要加上对应值出现的次数。
伪代码
python
unordered_map(int,int) map;
for(a:A):
for(b:B):
map[a+b]++;
for(c:C):
for(d:D):
target=0-(c+d)
if (map.find(target!=map.end()):
count+=map[target]
return count
写题
报错1

-
字典初始化错误 :
records[a+b]+=1会报KeyError,因为首次出现的a+b不在字典中,需先判断或用get初始化; -
变量引用错误 :第二个双层循环中误用
a+b(此时a、b已不在作用域),应该用-(c+d)去查字典; -
条件判断错误 :
records[a+b]==-(c+d)逻辑写反,正确逻辑是判断-(c+d)是否在records中,再取对应次数。
写了10行代码就有3个错怎么说
提交

python
class Solution(object):
def fourSumCount(self, nums1, nums2, nums3, nums4):
# 使用字典存储nums1和nums2中的元素及其和
hashmap = dict()
for n1 in nums1:
for n2 in nums2:
if n1 + n2 in hashmap:
hashmap[n1+n2] += 1
else:
hashmap[n1+n2] = 1
# 如果 -(n1+n2) 存在于nums3和nums4, 存入结果
count = 0
for n3 in nums3:
for n4 in nums4:
key = - n3 - n4
if key in hashmap:
count += hashmap[key]
return count
383. 赎金信
这个我自己写过了,没有看题解,和昨天那个字母异位词很像,思路差不多。
思路
统计magazine中每个字母的个数,有就加一
遍历ransomNote,遍历,有就减1
magazine的字母要大于等于ransomNote的字母
所以判断最后的哈希表是否小于0,小于0就是ransomNote出现了magzine里面没有的
写题

python
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
hash=[0]*26
for i in magazine:
hash[ord(i)-ord('a')]+=1
for i in ransomNote:
hash[ord(i)-ord('a')]-=1
for i in hash:
if i<0:
return False
return True
15. 三数之和
思路
也可以用哈希做,但是需要去重,细节比较多
双指针法,遍历用i进行,双指针一个是left,一个是right,
我们需要对数组进行从小到大排序,以便接下来的步骤。还有就是题目不要求返回下标。
三数之和为0,也就是nums[i]+nums[left]+nums[right]=0
如果这个结果大于0,需要将right左移
如果这个结果小于0,需要将left右移
等于0时,收集结果。
伪代码
python
sort(nums);
for(i=0;i<nums.size;i++):
if nums[i]>0://排序之后的最小值大于0,没有符合条件的结果
return
if (i>0 && nums[i]==nums[i-1]):/
/i>0确保下标不是负数,nums[i]==nums[i-1]去重
//但是不是对比nums[i]和nums[i+1](left),(-1,-1,2)是可以有这种结果的
left=i+1
right=nums.size-1
while(right>left)://right不可以等于left,否则就指向同一个数
if nums[i]+nums[left]+nums[right]>0:
right--
elif nums[i]+nums[left]+nums[right]<0:
left++
else:
result.push();
if(right>left && right[i]==right[i-1]):
right--
if(right>left && left[i]==left[i-1]):
left++
right-=1
left+=1
return res
写题
错误
1.去重的条件写错
python
while right>left and nums[left]==nums[left+1]:
写成nums[left]+1
2.把去重的层次写错了,写到和else并列,其实是在else里面
python
else:
res.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
提交

python
class Solution:
def threeSum(self, nums: list[int]) -> list[list[int]]:
res=[]
nums.sort()
for i in range(len(nums)):
if nums[0]>0:
return []
if i>0 and nums[i]==nums[i-1]:
continue
left=i+1
right=len(nums)-1
while left<right:
if nums[i]+nums[left]+nums[right]>0:
right-=1
elif nums[i]+nums[left]+nums[right]<0:
left+=1
else:
res.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 res
18. 四数之和
已经有一种难以呼吸的感觉了,是我太菜
写题
在三数之和的基础上又套了一层循环,其他逻辑差不多。

python
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
n=len(nums)
result=[]
for i in range(n):
if i>0 and nums[i]==nums[i-1]:
continue
for j in range(i+1,n):
if j>i+1 and nums[j]==nums[j-1]:
continue
left,right=j+1,n-1
while left<right:
s=nums[i]+nums[j]+nums[left]+nums[right]
if s>target:
right-=1
elif s<target:
left+=1
else:
result.append([nums[i],nums[j],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