力扣454.四数相加2
题目链接:https://leetcode.cn/problems/4sum-ii/
思路
1.计算数组A每个元素和数组B中每个元素的和,和出现的次数。
2.定义一个map,key值为a+b,value值为a+b出现的次数。
3.计算数组C每个元素和数组D中每个元素的和,记为temp。从map中找是否存在0-temp,找到了就返回key值为(0-temp)时对应的value值。
自己实现
看了题解想清楚了上述几个问题,自己写出了代码,还挺开心的。
完整代码
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=0;i<nums1.length;i++){
for(int j=0;j<nums2.length;j++){
int temp1=nums1[i]+nums2[j];
if(!map.containsKey(temp1)){
map.put(temp1,1);
}else{
map.put(temp1,map.get(temp1)+1);
}
}
}
for(int i=0;i<nums3.length;i++){
for(int j=0;j<nums4.length;j++){
int temp2=nums3[i]+nums4[j];
if(map.containsKey(0-temp2)){
res+=(map.get(0-temp2));
}
}
}
return res;
}
}
力扣383.赎金信
题目链接:https://leetcode.cn/problems/ransom-note/
思路
本题和有效的字母异位词一样的思路。唯一需要注意的点就是:例如,ransomNote=‘aa’,magazine=‘aab’,应该返回的是true。所以最后遍历res的判断条件要改改,只要字母数大于等于零就是true。
自己写出来的,耶!
完整代码
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] res=new int[26];
for(int i=0;i<ransomNote.length();i++){
res[ransomNote.charAt(i)-'a']--;
}
for(int i=0;i<magazine.length();i++){
res[magazine.charAt(i)-'a']++;
}
for(int count:res){
if(count<0) return false;
}
return true;
}
}
力扣15.三数之和
题目链接:https://leetcode.cn/problems/3sum/
思路
1.将数组排序,遍历数组元素,并让left=i+1,right为数组末尾元素。当i+left+right<0时,说明和太小,需要增大left;当i+left+right>0时,说明和太大,需要减小right。直至left和right相遇。
2.在遍历数组元素即i时,我们要考虑去重。例如(-1,-1,2),若写成
if(nums[i]==nums[i+1]){
continue;
}
就把三元组内有重复元素的情况去掉了。然而我们实际上是允许三元组内有重复元素的,不被允许的是有重复的三元组。
3.也要考虑left和right的去重。我们应该先把符合条件的三元组先加进结果中,再进行去重。例如(0,0,0),如果先进行去重,那这个三元组就不会被放进结果中了。
完整代码
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) return res;//排序后第一个元素大于零,肯定求不出三元组为0
if(i>0&&nums[i]==nums[i-1]) continue;
int left=i+1;
int right=nums.length-1;
while(left<right){
int sum=nums[i]+nums[left]+nums[right];
if(sum<0){
left++;
}else if(sum>0){
right--;
}else{
res.add(Arrays.asList(nums[i],nums[left],nums[right]));
while(right>left&&nums[right]==nums[right-1]) right--;
while(right>left&&nums[left]==nums[left+1]) left++;
right--;
left++;
}
}
}
return res;
}
}
力扣18.四数之和
题目链接:https://leetcode.cn/problems/4sum/
思路
和三数之和思路一致,只是再套一层for循环,同时也要注意对j的去重。
完整代码
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]>0&&nums[i]>target) return res;
if(i>0&&nums[i]==nums[i-1]) continue;
for(int j=i+1;j<nums.length;j++){
if(j>i+1&&nums[j]==nums[j-1]) continue;
int left=j+1;
int right=nums.length-1;
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[right]==nums[right-1]){right--;}
while(left<right&&nums[left]==nums[left+1]){left++;}
left++;
right--;
}
}
}
}
return res;
}
}
总结
贴一下卡哥的哈希表总结,刷到哈希表时常看看,哪种情况用哪种数据结构合适。