454.四数相加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 示例1: 输入:nums1 = [1, 2], nums2 = [-2, -1], nums3 = [-1, 2], nums4 = [0, 2] 输出:2 解释:两个元组如下: 1.(0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0 2.(1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0 示例2: 输入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0] 输出:1
class Solution:
def fourSumCount(self, nums1: int, nums2: int, nums3: int, nums4: int) -> int:
dict_num1 = {}
for i in range(len(nums1)):
for j in range(len(nums2)):
tmp = nums1[i] + nums2[j]
if tmp not in dict_num1:
dict_num1[tmp] = [[i,j]]
else:
dict_num1[tmp].append([i,j])
dict_num2 = {}
for i in range(len(nums3)):
for j in range(len(nums4)):
tmp = nums3[i] + nums4[j]
if tmp not in dict_num2:
dict_num2[tmp] = [[i,j]]
else:
dict_num2[tmp].append([i,j])
res = 0
for i in dict_num1:
for j in dict_num2:
if i + j == 0:
li = len(dict_num1[i])
lj = len(dict_num2[j])
tmp = li * lj
res += tmp
return res
if __name__ == '__main__':
nums1 = [1, 2]
nums2 = [-2, -1]
nums3 = [-1, 2]
nums4 = [0, 2]
tmp = Solution()
res = tmp.fourSumCount(nums1,nums2,nums3,nums4)
print(res)
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int> map1;
for(int i = 0; i < nums1.size(); i++){
for(int j = 0; j < nums2.size(); j++){
int tmp = nums1[i]+nums2[j];
map1[tmp]++;
}
}
int res = 0;
for(int i = 0; i < nums3.size(); i++){
for(int j = 0; j < nums4.size(); j++){
int tmp = nums3[i] + nums4[j];
if(map1.find(0-tmp) != map1.end()){
res += map1[0-tmp];
}
}
}
return res;
}
};
看了一下解法,因为只需要求计数,所以可以直接count计数,这样可以少循环一次。
383.赎金信
给你两个字符串:ransomNote和magazine ,判断ransomNote能不能由magazine里面的字符构成。 如果可以,返回true ;否则返回false 。 magazine中的每个字符只能在ransomNote中使用一次。 示例1: 输入:ransomNote = "a", magazine = "b" 输出:false 示例2: 输入:ransomNote = "aa", magazine = "ab" 输出:false 示例3: 输入:ransomNote = "aa", magazine = "aab" 输出:true
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
dic = {}
for i in ransomNote:
if i not in dic:
dic[i] = 1
else:
dic[i] += 1
dic_mag = {}
for j in magazine:
if j not in dic_mag:
dic_mag[j] = 1
else:
dic_mag[j] += 1
for k, v in dic.items():
tmp = dic_mag.get(k)
if tmp is None or v > tmp:
return False
return True
if __name__ == '__main__':
ransomNote = "aa"
magazine = "aab"
tmp = Solution()
res = tmp.canConstruct(ransomNote,magazine)
print(res)
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int alpha[26] = {0};
for(char a : magazine){
alpha[a - 'a']++;
}
for(char b: ransomNote){
alpha[b - 'a']--;
if(alpha[b - 'a'] < 0){
return false;
}
}
return true;
}
};
看了一下随想录,发现python有四种解法, 麻了
重写发现C++的写法很有意思
15.三数之和
给你一个整数数组nums ,判断是否存在三元组[nums[i], nums[j], nums[k]]满足i != j、i != k且 j != k ,同时还满足nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为0且不重复的三元组。 注意:答案中不可以包含重复的三元组。 示例1: 输入:nums = [-1, 0, 1, 2, -1, -4] 输出:[[-1, -1, 2], [-1, 0, 1]] 解释: nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。 不同的三元组是[-1, 0, 1]和[-1, -1, 2] 。 注意,输出的顺序和三元组的顺序并不重要。 示例2: 输入:nums = [0, 1, 1] 输出:[] 解释:唯一可能的三元组和不为0 。 示例3: 输入:nums = [0, 0, 0] 输出:[[0, 0, 0]] 解释:唯一可能的三元组和为0
class Solution:
def threeSum(self, nums):
long = len(nums)
res = []
nums.sort()
for i in range(long):
if i == long - 2:
break
left = i + 1
right = long - 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:
tmp = [nums[i], nums[left], nums[right]]
tmp.sort()
if tmp not in res:
res.append(tmp)
left += 1
return res
if __name__ == '__main__':
nums = [-1, 0, 1, 2, -1, -4]
nums = [0, 1, 1]
nums = [0, 0, 0,0]
nums = [-2, 0, 1, 1, 2]
tmp = Solution()
res = tmp.threeSum(nums)
print(res)
注意,这里是24年4月,上面的python写法已经被规避了,必须要掌握a,b,c 三种去重方法,第一种是对i的去重,是 i > 0 and nums[i] == num[i-1],第二种则是在获取到结果的此刻,判断 b 是否和b+1相等,但是注意,不能让b+1越界,且这是个持续动作,所以,是 right > left and nums[left ] == nums[left+1] ,c的判断方法和b等同。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(),nums.end());
int cnt = nums.size();
for(int i = 0; i < cnt; i++){
int start = i + 1;
int end = cnt - 1;
if(nums[i] > 0){
return res;
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
while(start < end){
int sum = nums[i] + nums[start] + nums[end];
if(sum == 0){
vector<int> tmp;
tmp.push_back(nums[i]);
tmp.push_back(nums[start]);
tmp.push_back(nums[end]);
res.push_back(tmp);
//[-2,0,0,2,2]这个示例指引去重
while(end > start and nums[end] == nums[end-1]){
end--;
}
while(end > start and nums[start] == nums[start+1]){
start++;
}
start++;
end--;
}
else if(sum > 0){
end--;
}
else{
start++;
}
}
}
return res;
}
};
18. 四数之和
给你一个由n个整数组成的数组nums ,和一个目标值target 。请你找出并返回满足下述全部条件且不重复的四元 组[nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复): 0 <= a, b, c, d < n a、b、c和d互不相同 nums[a] + nums[b] + nums[c] + nums[d] == target 你可以按任意顺序返回答案 。 示例1: 输入:nums = [1, 0, -1, 0, -2, 2], target = 0 输出:[[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]] 示例2: 输入:nums = [2, 2, 2, 2, 2], target = 8 输出:[[2, 2, 2, 2]]
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
cnt = len(nums)
res = []
for i in range(cnt-2):
if i > 0 and nums[i] == nums[i-1]:
continue
for j in range(i+1,cnt-2):
if j > i + 1 and nums[j] == nums[j-1]:
continue
k = j + 1
m = cnt - 1
while k < m:
sum_ = nums[i] + nums[j] + nums[k] + nums[m]
if sum_ == target:
tmp = [nums[i], nums[j], nums[k], nums[m]]
# if tmp not in res:
# res.append(tmp)
res.append(tmp)
while m > k and nums[k] == nums[k+1]:
k += 1
while m > k and nums[m] == nums[m-1]:
m -= 1
k += 1
m -= 1
elif sum_ > target:
m -= 1
else:
k += 1
return res
第四题需要再看看,压力好大啊,这个节奏真的快
这里需要思考一下四层去重
1.第一个数的去重和三数之和一样,a > 0 and nums[a] == nums[a-1];
2.第二个数的去重是基于第一个数,所以和第一个数的条件不同,b=a+1,他需要和前一个数对比,但是前一个数不能是a,所以要往前一格,即 b > a + 1 and nums[b] == nums[b-1];
3.第三和第四个数就和三数之后的道理一样了,在获取到结果的前提下,满足 d > c ,然后 nums[c] 和 nums[c+1]相比,nums[d] 和 nums[d-1]相比,然后c向前,d向后。
4.注释行的代码可以代替a和b的去重。