代码随想录算法训练营Day6 | Leetcode 454四数相加II、383赎金信、15三数之和、18四数之和
一、四数相加II
相关题目:Leetcode454
文档讲解:Leetcode454
视频讲解:B站代码随想录
1. Leetcode454.四数相加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
-
思路:
- 所给出的数组相互独立,不用考虑有重复的四个元素相加等于0的情况。
- 首先定义 一个 dict,遍历 nums1 和 nums2 数组,key 存数组元素 n1,n2 两数之和,value 存两数之和出现的次数。
- 定义 int 变量 count,遍历 nums3 和 nums4数组,若 0 - (n1 + n2) 在 dict 中出现,则 count 统计 dict 中 key 对应的 value,最后返回统计值。
-
复杂度
使用字典 | 使用defaultdict | |
---|---|---|
时间复杂度 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) |
空间复杂度 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) |
- 使用字典
class Solution(object):
def fourSumCount(self, nums1, nums2, nums3, nums4):
# 使用字典存储nums1和nums2中的元素及其和
hashmap = dict()
for n1 in nums1:
for n2 in nums2:
hashmap[n1+n2] = hashmap.get(n1+n2, 0) + 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
- 使用defaultdict
from collections import defaultdict
class Solution:
def fourSumCount(self, nums1: list, nums2: list, nums3: list, nums4: list) -> int:
rec, cnt = defaultdict(lambda : 0), 0
for i in nums1:
for j in nums2:
rec[i+j] += 1
for i in nums3:
for j in nums4:
cnt += rec.get(-(i+j), 0)
return cnt
二、赎金信
相关题目:Leetcode383
文档讲解:Leetcode383
1. Leetcode383.赎金信
给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)
注意:可以假设两个字符串均只含有小写字母。
- 思路:
- 类似于 Leetcode242.有效的字母异位词,字符串只含有小写字母,故可以用长为26的数组记录出现的字母次数,再进行对比即可。
- 注意:
- 已知是小写字母,数组实现会比字典实现稍快、更省空间;字典实现更灵活,但有哈希表额外开销。
- 字典更适用场景:
- 字符集未知或较大(如 Unicode 字符、大小写字母、符号混杂)。
- 数据稀疏,数组浪费空间时。
- 需要更清晰、简洁代码,牺牲部分性能换易读性。
- 复杂度
n 是 ransom 长度,m 是 magazine 长度。
使用数组 | 使用defaultdict | 使用字典 | |
---|---|---|---|
时间复杂度 | O ( n + m ) O(n+m) O(n+m) | O ( n + m ) O(n+m) O(n+ |