383. 赎金信
11/20二刷,还是和第一次做一样的思路,想不到用hashmap
后来看了题解和视频,终于明白了。和valid anagram那道题一样。用ord转换成ASCII的方式做
这道题可以用数组,因为都是小写字母,创造一个array = [0]*26
15. 三数之和
#复杂在去重,三元组
#使用hash法做这道题很复杂,去重的细节太多了
#更易于理解的是双指针法
#先数组排序,因为求元素值,没要求下标,求下标的话排序后下标就乱了
#用for循环遍历,i,也就是a确定后,b就是left,c是right
#如果三个数相加大于0,就让right往里移一位,如果小于0,就left往外移一位,因为这是排好序的
#细节也在于去重
#我们是判断nums[i]和nums[i+1]是否相等,还是nums[i]和nums[i-1]是否相等?
#nums[i+1]其实就是left,如果是判断nums[i]和nums[i+1]是否相等,就等于判断i和left是否相等
#题目要求是三元组不重复,里面元素可以重复,所以不行'
result = []
sort = sorted(nums)
if sort[0] > 0:
return []
#l = 0 #错了,l不能设置为0,i是从0开始的,l在i后面
r = len(nums)-1
for i in range(len(sort)):
l = i+1
while l < r:
if sort[i] + sort[l] + sort[r] == 0:
result.append([sort[i],sort[l],sort[r])
elif sort[i] + sort[l] + sort[r] > 0:
r -= 1
elif sort[i] + sort[l] + sort[r] < 0:
l += 1
return result
454.四数相加② def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
#毫无头绪
#这道题只要求数量,简单的地方:不用去重,即使数组都是[0,0,0,0],但是在不同的位置,所以也是不同的
#思路:字母异位题里面,是用数组做hashmap,因为都是小写字母,最多26个,数量是有限的,所以可以用数组
#这道题,数据可能很大,所以不能用数组,只能用set或者map
#我们需要统计出现过的次数和value,所以set不行,需要map【c++叫map,java叫hashmap,python叫dict】
#代码实现有问题,result +=1 是不对的.
#以sumab为value,sumab出现的次数为key,存入dict.创建空字典后,如何添加key-value对?
#思路:把4个数组分成两份(其实分成1+3也可以,但复杂度高),先计算两个数组的sum,然后存储进dict,dict的value是n1+n2,key是(n1+n2)出现的次数。
#再把第三第四数组加起来,计算(target-n3-n4)有没有在dict种出现过,这样就等于转换成two sum题了
dictab = {}
result = 0
for n1 in nums1:
for n2 in nums2:
if (n1+n2) in dictab:
dictab[n1+n2] += 1
else:
dictab[n1+n2] = 1 #(n1+n2)的sum是value,sum出现的次数是key
for n3 in nums3:
for n4 in nums4:
if -(n3+n4) in dictab:
result += dictab[-n3-n4] #注意,统计次数,这里不是+=1,而是+=value,也就是dict中的key
return result
18. 四数之和 |
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
#思路:和三数之和几乎都一样,就是加了一次循环,现在是双指针+双循环。本来我还在想是不是三指针,但不是。细节还是在于去重的知识没有掌握,尤其是下面那层去重。意外的是,nums.sort()和sorted(nums)是有区别的,我用sorted(nums)就报错,改成nums.sort()就通过。但以前一直用sorted(nums)都没问题。
#sort = sorted(nums) #会报错!!!!!
sort = nums
sort.sort() #要在原函数上直接.sort(),但因为我之前搞了个函数sort = sorted(nums),不想改下面的代码,就这么改了。
result = []
for i in range(len(sort)):
if i > 0 and sort[i] == sort[i-1]:
continue #如果循环里有很多逻辑 提前continue就少了一次循环内的操作
for j in range(i+1,len(sort)):
if j > i+1 and sort[j] == sort[j-1]:
continue
l = j+1
r = len(sort)-1
while l < r:
if sort[i] + sort[j] + sort[l] + sort[r] > target:
r = r-1
elif sort[i] + sort[j] + sort[l] + sort[r] < target:
l = l+1
else:
result.append([sort[i],sort[j],sort[l],sort[r]])
while l < r and nums[l] == nums[l + 1]:
l += 1
while l < r and nums[r] == nums[r - 1]:
r -= 1
l += 1 #这步老是漏掉,没搞懂
r -= 1 #这步老是漏掉,没搞懂
return result