今日任务
- 454.四数相加II
- 383. 赎金信
- 15. 三数之和
- 18. 四数之和
- 总结
LeetCode454 四数相加
题目链接:454. 四数相加
思路:
首先,返回个数,所以建立以a+b总和sum为key,以个数为value的map
最终取符合key=a+b=0-c-d的key值,其value即个数,需要对value进行累加得到总元组个数。
● 用到的函数:
map.get(key)
map.getOrDefault(key)有就加一,没有就创建出初始值为0
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int count = 0;
Map<Integer,Integer> map1 = new HashMap<>(); //key:元素值之和,value:这个数值出现的次数
for(int a : nums1){
for(int b : nums2){
//map1[a+b]++; 注意java不能这么写
map1.put(a+b,map1.getOrDefault(a+b,0)+1);
}
}
for(int c: nums3){
for(int d: nums4){
int tmp = 0 -c-d;
if(map1.containsKey(tmp)){
count += map1.getOrDefault(tmp,0);
}
}
}
return count;
}
}
LeetCode383 赎金信
题目链接:383.赎金信
思路:是否存在?用数组
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] record = new int[26];
for(int i=0;i<magazine.length();i++){
record[magazine.charAt(i)-'a']++;
}
for(int j=0;j<ransomNote.length();j++){
record[ransomNote.charAt(j)-'a']--;
if(record[ransomNote.charAt(j)-'a']<0){
return false;
}
}
return true;
}
}
LeetCode15 三数之和
题目链接:15. 三数之和
思路:1. 两数之和 这道题需要求出两个数(key)对应的下标(value),不要求去重
而这道题明确要求给出不重复的三元组
因此应首先用双指针法,即首先进行排序,
在一个i的for循环中,通过left和right指针来找到合适的三元组
但是为了使三元组不重复,i不能重复,left和right也不能重复(对abc都要做出剪枝的操作)
● Arrays.sort(); 对数组从小到大进行排序 Arrays.asList(a,b,c); 将数组转化成list[a,b,c]
● 动态三元组[ [a,b,c ], [ a,b,c] ]:List <List<Integer>> res = new ArrayList<>();
●区别 arraylist数组,集合set,和映射map用的不同函数
代码:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
for(int i= 0; i<nums.length;i++){
if(nums[i]>0){
break;
}
if(i>0 && nums[i] == nums[i-1]){
continue;
}
int left = i+1;
int right = nums.length - 1;
int sum = nums[i] + nums[left] + nums[right];
while(left<right){
if(sum<0) left++;
else if(sum>0) right--;
else{
res.add(Arrays.asList(nums[i],nums[left],nums[right]));
//必须加入right>left的判断条件以免移动的过头
while(right > left && nums[left]==nums[left+1]) left++;
while(right > left && nums[right]==nums[right-1]) right--;
// 双指针本身还是要移动的
left++;
right--;
}
}
}
return res;
}
}
LeetCode18 四数之和
题目链接:18.四数之和
思路:比三数之和多了一重for循环和去重的操作
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
if(nums[i]>target){ //剪枝
break;
}
if(i > 0 && nums[i] == nums[i-1]){ //对nums[i]去重
continue;
}
for(int j=i+1;j<nums.length;j++){
if(j > i+1 && nums[j] == nums[j-1]){ //对nums[j]去重(允许j=i+1的首次情况发生)
continue;
}
int left = j+1;
int right = nums.length-1;
//因为left、right都在变,所以不能放在外面
//int sum = nums[i]+nums[j]+nums[left]+nums[right];
while(left<right){
int sum = nums[i]+nums[j]+nums[left]+nums[right];
if(sum>target)right--;
else if(sum<target)left++;
else{
res.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
while(left<right && nums[left]==nums[left+1])left++;
while(left<right && nums[right]==nums[right-1])right--;
left++;
right--;
}
}
}
}
return res;
}
}