代码随想录算法训练营第六天| 454.四数相加II,383. 赎金信的交集, 15.三数之和(需要二刷) 18.四数之和(需要二刷)

454.四数相加II

暴力超时

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        //超出时间限制
        //分别从4个数组中任选一个,四数相加==0
       int  n = nums4.length,index=0;
       
       int count=0;

       int[] arr1=new int[n*n];
        int[] arr2=new int[n*n];
        int m=arr1.length;
        
        
       //两辆数组先做加法,找出所有可能
       for(int i=0;i

卡在这个用例[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

优化,看了下题解用HasMap,思路是差不多的,都是先求两个数组的所有可能元素之和放到map中,然后在map中寻找另外两个数组的所有可能元素之和的相反数

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
       
        //分别从4个数组中任选一个,四数相加==0
        int n=nums1.length;
       int count=0;
        Map map=new HashMap();

       //数组先做加法,找出所有可能的和
       for(int i=0;i

383. 赎金信

这道题和242. 有效的字母异位词的思路一样,写的很顺

class Solution {
    public boolean canConstruct(String r, String m) {
        //判断 ransomNote 能不能由 magazine 里面的字符构成。magazine 中的每个字符只能在 ransomNote 中使用一次。
        int[] letter=new int[26];
        for(int i=0;i0){//说明r有字符没有使用到m中的字符
               return false;
           }
        }
        return true;
    }
}

 15.三数之和(需要二刷)

15. 三数之和 

很细节的题目,没有思路

class Solution {
    public List> threeSum(int[] nums) {
        //哈希?双指针其实可以理解成是三指针
        int len=nums.length;
        List> res=new ArrayList<>();
        if(nums == null || len <3){
            return res;
        }
        //排序
        Arrays.sort(nums);
        //遍历数组中的每一个元素
        for(int i=0;i0){
                break;
            }
            //去重,当起始值等于前一个元素时,得到的结果会和前一次相同
            if(i>0&&nums[i]==nums[i-1]){continue;}//这里先i>0避免i=0时这里报错
            int l=i+1;
            int r=len-1;
            //当l不等于r时就继续遍历
            while(l0
                    r--;
                }
            }
        }
        return res;
    }
}

两行while代码解决下面示例的情况

代码随想录算法训练营第六天| 454.四数相加II,383. 赎金信的交集, 15.三数之和(需要二刷) 18.四数之和(需要二刷)_第1张图片

 

 18.四数之和(需要二刷)

思路和15.三数之和一样,

只不过四数是要两层for循环,先确定一个sum=nums[i]+nums[k]

再判断sum2=sum+nums[l]+nums[r]是否等于target,

target值是否合法判断:将数组nums升序后,比较target和nums[0]

去重判断:

1.if(i > 0 && nums[i - 1] == nums[i]) {  continue;}
2.if(k>i+1&&nums[k]==nums[k-1]){continue;}//去重
3.while(l

代码:

class Solution {
    public List> fourSum(int[] nums, int target) {
        //四树之和II给的是4个数组,且索引下标允许相同
        //双指针,和15.三数之和类似
        int len=nums.length;
        List> res=new ArrayList<>();
        if(nums == null || len <4){
            return res;
        }
        //排序
        Arrays.sort(nums);
       
        for(int i=0;i 0 && nums[i] > target) { //如果遍历的起始元素大于target,那么就直接退出 //原因,此时数组为有序的数组,最小的数都大于target了,四数之和肯定大于target
                return res;
            }
		
            if (i > 0 && nums[i - 1] == nums[i]) {    // 对nums[i]去重
                continue;
            }
            for(int k=i+1;ki+1&&nums[k]==nums[k-1]){continue;}//去重

               int l=k+1;
               int r=len-1;
            //当l不等于r时就继续遍历
               while(l0
                    r--;
                }
               }

            }
            
        }
        return res;

    }
}

你可能感兴趣的:(算法,数据结构)