Day07:454.四数相加、383.赎金信、15.三数之和、18.四数之和
454.四数相加
原题链接:
454.四数相加
代码随想录链接:
这道题因为有四个整数数组,并且长度相等,结果集内可以有相同的元素,所以这道题不用去进行复杂的剪枝和去重操作。
思路如下:
- 先定义一个map集合,双层for循环遍历前面两个数组,把前面两个数组的数之和放入到map集合中,key值为和,value值为该和出现的次数;
- 之后再使用双层for循环遍历后面两个数组,如果map中能找到0减去遍历的两个数组之中的数,说明找到了一组正确的结果,这个时候结果result加0,最后再返回result即可;
Java源代码如下:
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int result = 0;
Map<Integer,Integer> map = new HashMap<>();
for(int i : nums1){
for(int j :nums2){
map.put(i+j,map.getOrDefault(i+j,0)+1);
}
}
for(int i : nums3){
for(int j : nums4){
result += map.getOrDefault(0-i-j,0);
}
}
return result;
}
}
383.赎金信
原题链接:
代码随想录链接:
这一题我是使用map去做的,但是做出来之后时间空间都消耗很大,因为map要维护红黑树或者哈希表,而且还要做哈希函数,是费时的!数据量大的话就能体现出来差别了,于是去看了代码随想录的解析
发现卡哥的解析是使用了数组的哈希法应用,瞬间一拍脑袋说我怎么没想到,于是自己回去用数组重写了一遍,发现真的简单很多,整体思路如下:
- 先定义一个大小为26的整数数组用来存放每个字符出现的次数
- 之后遍历一遍
magazine
这个字符串,把里面的字符出现的次数加入数组 - 然后遍历一遍
ransomNote
这个字符串,里面的字符出现一次,对应数组的位置数-1 - 最后遍历整数数组,如果发现数组内有数小于0,说明
magazine
不能包含ransomNote
,返回false,for循环外返回true;
Java源代码如下:
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if(ransomNote.length() > magazine.length()){
return false;
}
int[] result = new int[26];
for(char c : magazine.toCharArray()){
result[c - 'a'] += 1;
}
for(char c : ransomNote.toCharArray()){
result[c - 'a'] -= 1;
}
for(int i : result){
if(i < 0){
return false;
}
}
return true;
}
}
15.三数之和、18.四数之和
这两题太难了,我第一次听到剪枝和去重的操作,建议大家去看卡哥的B站讲解视频,这里给出链接:
15.三数之和
18.四数之和
卡哥三数之和B站讲解视频
卡哥四数之和B站讲解视频