mgaw

导航

代码随想录算法训练营第七天| 454 四数相加 II 383 赎金信 15 三数之和 18 四数之和

目录

383 赎金信

15 三数之和

 454 四数相加 II

18 四数之和


383 赎金信

该题与242 有效的字母异位词思路相同

首先想到暴力写法,遍历magazine,将遍历到的元素记为ch,再遍历ransomNote,如果在ransomNode中找到了ch,就将两个字符串中的ch都删除,遍历完成后,如果ransomNode为空,则ransomeNode能由magazine里面的字符构成。时间复杂度O(n^2),空间复杂度为O(1)。

需要判断字符是否存在于字符串中,由此想到哈希解法,由题目提示 ransomNote 和 magazine 由小写英文字母组成我们可知只需开辟一个大小为26的cnt数组进行存储,首先将遍历magazine,每遍历到一个字符,先将字符 - 'a'映射到0~25区间内,再进行一次++操作,接着遍历ransomNode,将字符-'a'之后进行一次--操作。最后遍历cnt数组,如果有小于0的值则可以判定ransomeNode不能由magazine里面的字符构成。

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        if(ransomNote.length() > magazine.length())return false;
        int cnt[] = new int[26];
        for(char ch : magazine.toCharArray()){
            cnt[ch - 'a'] ++;
        }
        for(char ch: ransomNote.toCharArray()){
            cnt[ch - 'a']--;
        }
        for(int i = 0;i < 26;i++){
            if(cnt[i] < 0)return false;
        }
        return true;
    }
}

时间复杂度O(m + n),空间复杂度O(1)。

15 三数之和

采用双指针做法,先使nums按照非递减顺序排列,在循环中用i遍历nums取得,并对nums[i]进行去重操作,如果nums[i]大于0则一定不成立,退出循环并返回答案res。记i+1为l,nums.length-1为r,在第二层循环中求得三者之和sum后,如果三者之和大于0,则r--,小于,则l++,直至等于0后退出此循环并且进行对l与r的去重操作,最终加入res作为答案返回。

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;
            if(i >= 1 && nums[i] == nums[i - 1])continue;
            int l = i + 1,r = nums.length - 1;
            while(r > l){
                int sum = nums[l] + nums[r] + nums[i];
                if(sum > 0)r--;
                else if(sum < 0)l++;
                else{
                    res.add(Arrays.asList(nums[i],nums[l],nums[r]));
                    while(r > l && nums[r] == nums[r - 1])r--;
                    while(r > l && nums[l] == nums[l + 1])l++;
                    r--;l++;
                }
            }
        }
        return res;
    }
}

时间复杂度O(n^3),空间复杂度O(n)。

 454 四数相加 II

由于本题不需要去重操作,可以使用哈希方法。在两层循环中遍历nums1与nums2 将和加入到map中。遍历nums3与nums4,在map中查找二者之和的负数的值,返回值res加上该值。

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4){
        Map<Integer,Integer> mp = new HashMap<>();
        int res = 0;
        for(int i : nums1){
            for(int j : nums2){
                int sum = i + j;
                if(mp.containsKey(sum)){
                    mp.put(sum,mp.get(sum) + 1);
                }else{
                    mp.put(sum,1);
                }
            }
        }
        for(int i : nums3){
            for(int j : nums4){
                int sum = 0 - (i + j);
                if(mp.containsKey(sum))res += mp.get(sum);
            }
        }
        return res;
    }
}

map.containsKey(key);取得map中key键的值

map.put(sum,cnt)设置key键的值为cnt

map.get(key)取得key键的值

时间复杂度O(n^2),空间复杂度O(n^2)。

18 四数之和

先使nums按非递减顺序排序。第一层循环中用i遍历nums,并进行去重操作,令j=i+1在第二层循环中进行遍历并去重,定义l等于j+1,r等于nums.length-1,在第三层循环计算sum等于四者相加,如果sum小于target则l++,大于则r--,当相等时对l与r进行去重,并加入到结果res中。

由于相比15 三数之和 (该题target为0,已经确定)本题target可以取负值,在进行剪枝操作时应该注意加上nums[i] > 0条件。样例 nums=[-4,-3,-2,-1],target = -10,这里nums[i] > target,但确实应该将nums加入到res中。

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 l = j + 1,r = nums.length - 1;
                while(r > l){
                    int sum = nums[i] + nums[j] + nums[l] + nums[r];
                    if(sum > target)r--;
                    else if(sum < target)l++;
                    else{
                        res.add(Arrays.asList(nums[i],nums[j],nums[l],nums[r]));
                        while(r > l && nums[r] == nums[r - 1])r--;
                        while(r > l && nums[l] == nums[l + 1])l++;
                        r--;l++;
                    }
                }
            }
        }
        return res;
    }
}

时间复杂度O(n^3),空间复杂度O(n)。

posted on 2023-10-30 16:02  A魔法恐龙  阅读(9)  评论(0)    收藏  举报  来源