代码随想录算法训练营第七天|454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和、总结
454.四数相加II
题目
代码与思考过程
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer, Integer> map = new HashMap<>();//设置一个hashmap
int sum;
int result=0;
for(int i=0;i<nums1.length;i++){//求出nums1+2的总和
int num1 =nums1[i];
for(int j=0;j<nums2.length;j++){
int num2=nums2[j];
sum=num1+num2;
if(map.containsKey(sum)){//如果出现重复的sum
map.put(sum,map.get(sum)+1);//将value进行+1操作
}else{
map.put(sum,1);//无,这加入map
}
}
}
for(int i=0;i<nums3.length;i++){//求出nums3+4的总和
int num3=nums3[i];
for(int j=0;j<nums4.length;j++){
int num4=nums4[j];
sum=num3+num4;
if(map.containsKey(0-sum)){//如果出现重复的0-sum
result+=map.get(0-sum);//让结果等于map的value
}
}
}
return result;
}
}
对于这题我有意识到用双加然后做减法,但是我一开始没有用map(想试一下数组可不可以,顺便试一下自己)而且我但是也不知道map之中key和value分别存放什么东西,所以就没有用map后面自己想不到,就看过程了,因为已经2刷一遍所以就很容易看懂了
383. 赎金信
题目
代码与思考过程
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[]find=new int[26];//设立26字母
for(int i=0;i<magazine.length();i++){
find[magazine.charAt(i)-'a']++;//让ma每个元素都与a的ASCII进行相减
}
for(int i=0;i<ransomNote.length();i++){
find[ransomNote.charAt(i)-'a']--;//让ran每个元素都与a的ASCII进行相减
}
for(int i=0;i<find.length;i++){
if(find[i]<0){//小于0意味着有不相同的元素
return false;
}
}
return true;
}
}
有一说一,我看到的时候就已经知道要用数组来进行了,跟242.有效的字母异位词 思路是一致,就是找到26个小写字母的ascii码。
15. 三数之和
题目
代码与思考过程
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();//!!!!!!
int left;
int right;
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]){//进行i的去重处理
continue;
}
left=i+1;
right=nums.length-1;
while(left<right){
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(right>left&&nums[right]==nums[right-1]){//进行right的去重处理
right--;
}
while(right>left&&nums[left]==nums[left+1]){//进行left的去重处理
left++;
}
right--;
left++;
}
}
}
return result;
}
}
对于这个题目我一开始想用跟四数相加II一样的方法但是,我看了输出的result,好像返回不是一个东西,要进行去重,然后死在去重,因为没有排序,想用for循环,想了一下会超时,就选择观看答案了。
去重处理就是i那里要注意i-1,因为i+1是left,遇到[-1,-1,2]就不行!
18. 四数之和
题目
代码与思考过程
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]>0&&nums[i]>target){
return result;
}
if(i>0&&nums[i]==nums[i-1]){
continue;
}
for(int j=i+1;j<nums.length;j++){
if (j > i + 1 && nums[j - 1] == nums[j]) {
continue;
}
int left=j+1;
int right=nums.length-1;
while(right>left){
if(nums[i]+nums[j]+nums[left]+nums[right]>target){
right--;
}
else if(nums[i]+nums[j]+nums[left]+nums[right]<target){
left++;
}else{
result.add(Arrays.asList(nums[i],nums[j] ,nums[left], nums[right]));
while(right>left&&nums[right]==nums[right-1]){
right--;
}
while(right>left&&nums[left]==nums[left+1]){
left++;
}
left++;
right--;
}
}
}
}
return result;
}
}
因为返回的值和三数之和是一样的所以过程基本一致就是多一层for,注意一下j和j-1就可以了!
总结
对于类似454那种题目输出的是出现次数,可以不用去重操作的时候就可以使用一下map来进行寻找元素。而383. 赎金信就是242.有效的字母异位词 就是变了一下代码一些顺序就没有了,甚至基本一致!
15. 三数之和、18. 四数之和是一种类型的题目,题目要求的是求他的元组,然后要进行去重(元组不能有重复元素)用hash去重就很麻烦。(其实我感觉可以用map,当value多于1时候continue )用双指针就相对于简单,所以要与之前的知识相结合来做!List<List> result = new ArrayList<>();(多元组的创建是这样的)Map<Integer, Integer> map = new HashMap<>();//设置一个hashmap