第一题 四数相加II
题目描述:
给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
思路:
面对这种题,最简单直观的想法就是穷举出所有符合结果的组合。直接根据要求很容易写出O(n^4)的代码,如果使用哈希表中的hashmap就能有效降低时间复杂度。思路如下,首先需要将问题分解为两部分,一个是a+b,另一部分是0 - (c+d),在前两个数组中用hashmap的key记录a+b的值,value记录次数,接着计算c+d的值,同时设计一个计数值count,如果0 - (c+d)在hashmap之中,count加上hashmap的value。具体代码如下:
from typing import List
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
hashmap = dict()
for i in nums1:
for j in nums2:
if i+j in hashmap:
hashmap[i+j] += 1
else:
hashmap[i+j] = 1
count = 0
for i in nums3:
for j in nums4:
if 0-(i+j) in hashmap:
count += hashmap[0-(i+j)]
return count
if __name__ == '__main__':
solution = Solution()
nums1 = [1,2]
nums2 = [-2,-1]
nums3 = [-1,2]
nums4 = [0,2]
print(solution.fourSumCount(nums1, nums2, nums3, nums4))
第二题 赎金信
题目描述:
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以,返回 true ;否则返回 false 。magazine 中的每个字符只能在 ransomNote 中使用一次。
思路:
集合包含问题,使用哈希表统计次数,在根据次数去匹配,具体代码如下:
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
hashmap = dict()
for s in magazine:
if s in hashmap:
hashmap[s] += 1
else:
hashmap[s] = 1
strlen = len(ransomNote)
for i in ransomNote:
if i in hashmap and hashmap[i] > 0:
hashmap[i] -= 1
strlen -= 1
return strlen == 0
if __name__ == '__main__':
solution = Solution()
ransomNote = "a"
magazine = "b"
print(solution.canConstruct(ransomNote, magazine))
第三题 三数之和
题目描述:
思路:
这道题本来想用哈希表先记录0-(a+b)的值,然后在进行一次遍历。但是这样操作有一个问题,用哈希表会被误判。例如一个数组[3, 1, -1, 2],哈希表值为[-4, -5, 0, -2, -1, -3],检测到 -1 在哈希表中返回真,再去反向查找a+b,最终返回正确结果,本例子中根本就没有合法的结果。鉴于此,我们改进了算法,首先先排序,接着在判断重复,在使用哈希表。具体代码如下:
from typing import List
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
result = list()
for i in range(len(nums)):
if nums[i] > 0:
break
if i > 0 and nums[i] == nums[i-1]:
continue
hashmap = dict()
for j in range(i+1, len(nums)):
if j > i + 2 and nums[j] == nums[j-1] == nums[j-2]:
continue
tmp = 0 - (nums[i] + nums[j])
if tmp in hashmap:
result.append([nums[i], nums[j], tmp ])
hashmap.pop(tmp)
else:
hashmap[nums[j]] = j
return result
if __name__ == '__main__':
solution = Solution()
nums = [-1,0,1,2,-1,-4]
print(solution.threeSum(nums))
第四题 四数之和
题目描述:
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复)
思路:
思路和三数之和一致,就是加一个for循环,0改为target。具体代码如下
from typing import List
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
hashmap = dict()
for s in nums:
if s in hashmap:
hashmap[s] += 1
else:
hashmap[s] = 1
anser = set()
for i in range(len(nums)):
for j in range(i+1, len(nums)):
for k in range(j+1, len(nums)):
val = target - (nums[i] + nums[j] + nums[k])
if val in hashmap:
count = (nums[i] == val) + (nums[j] == val) + (nums[k] == val)
if hashmap[val] > count:
anser.add(tuple(sorted([nums[i], nums[j], nums[k], val])))
return [list(x) for x in anser ]
if __name__ == '__main__':
solution = Solution()
nums = [1,0,-1,0,-2,2]
target = 0
print(solution.fourSum(nums, target))