454.四数相加II
因为只需要输出组合的个数而且不用考虑有重复的四个元素相加等于0的情况,所以只需要定义一个map保存值和个数即可,解题步骤也比较简单就是key放a,b的和,value放和出现的次数,遍历A,B数组把map初始化,再定义一个count来统计a+b+c+d出现的次数,再遍历C,D数组,如果 0-(c+d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来,主要还是掌握put,getOrDefault这些方法。
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer,Integer> map=new HashMap<>();
int res=0;
for(int i: nums1){
for(int j: nums2){
int count = map.getOrDefault(i+j, 0);
count++;
map.put(i+j,count);
}
}
for(int p: nums3){
for(int q: nums4){
res += map.getOrDefault(0-(p+q), 0);
}
}
return res;
}
}
383. 赎金信
基本与242.有效的字母异位词一致,都是定义一个数组,以字母-'a'为下标,然后遍历完进行存储字符串,先用magazine构建然后去遍历randomnote去减有负数就结束了
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length()) {
return false;
}
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']--;
}
for(int i : record){
if(i < 0){
return false;
}
}
return true;
}
}
第15题. 三数之和
不适合用hash,可以用双指针,主要关键点在于剪枝 以及去重,去重注意nums[i]==nums[i-1],还有相等情况下的去重
//一直判断这个循环因为不一定只有一个重复元素,所以需要重新判断while
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
还有个add(Arrays.asList())方法
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int i=0;i<nums.length;i++){
if(nums[i]>0){
return result;
}
if(i>0&&nums[i]==nums[i-1]){
continue;//去重
}
int left=i+1;
int right=nums.length-1;
while(right>left){
if(nums[i]+nums[left]+nums[right]>0){
right--;
}
else if(nums[i]+nums[left]+nums[right]<0){
left++;
}
else{
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
//一直判断这个循环因为不一定只有一个重复元素,所以需要重新判断while
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
right--;
left++;
}
}
}
return result;
}
}
第18题. 四数之和
逻辑基本一致,需要注意要先判断是不是大于0否则i-1就会指向nums[-1]这样就会报错,因为排完序后nums[j]一定是大于nums[i]的,所以没必要再次去剪枝
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result=new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
if(nums[i]>target && nums[i]>0){
return result;
}
// 要先判断是不是大于0否则i-1就会指向nums[-1]这样就会报错
if(i>0 && nums[i]==nums[i-1]){
continue;
}
for(int j=i+1;j<nums.length;j++){
//因为排完序后nums[j]一定是大于nums[i]的,所以没必要再次去剪枝
// if(nums[i]>target &&nums[i]>0) return result;
if (j > i + 1 && nums[j - 1] == nums[j]) { // 对nums[j]去重
continue;
}
int left=j+1;
int right=nums.length-1;
while(left<right){
if(nums[i]+nums[j]+nums[left]+nums[right]<target){
left++;
}
else if(nums[i]+nums[j]+nums[left]+nums[right]>target){
right--;
}
else{
result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
while(left<right && nums[right]==nums[right-1]) right--;
while(left<right && nums[left]==nums[left+1]) left++;
left++;
right--;
}
}
}
}
return result;
}
}