代码随想录二刷第六天 | 454.四数相加II、383. 赎金信、15. 三数之和、18.四数之和

61 阅读2分钟

454题.四数相加II

题目:454. 四数相加 II - 力扣(LeetCode)

题解:代码随想录 (programmercarl.com)

状态:AC

思路

两层for遍历前两个并用一个Map存储前两个的和,再两层for遍历后两个相加求解

代码

时间复杂度:O(n^2) 空间复杂度:O(1)

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int res = 0;
        Map<Integer, Integer> map = new HashMap<>();
        for(int i : nums1){
            for(int j : nums2){
                int temp = i + j;
                map.put(temp, map.getOrDefault(temp, 0) + 1);
            }
        }

        for(int k : nums3){
            for(int l : nums4){
                res += map.getOrDefault(0 - k - l, 0);
            }
        }

        return res;
    }
}

383. 赎金信

题目:383. 赎金信 - 力扣(LeetCode)

题解:代码随想录 (programmercarl.com)

状态:

思路

一个Map(或者26位字符数组)记录第一个字符串各字符出现次数,之后遍历第二个字符串递减对应字符次数。

代码

时间复杂度:O(n) 空间复杂度:O(1)

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        Map<Integer, Integer> map = new HashMap<>();
        for(char c : magazine.toCharArray()){
            int temp = c - 'a';
            map.put(temp, map.getOrDefault(temp, 0) + 1);
        }
        for(char c : ransomNote.toCharArray()){
            int temp = c - 'a';
            int cur = map.getOrDefault(temp, 0);
            if(cur == 0){
                return false;
            }
            map.put(temp, cur - 1);
        }
        return true;
    }
}

15. 三数之和

题目:15. 三数之和 - 力扣(LeetCode)

题解:代码随想录 (programmercarl.com)

状态:需要多复习

思路

由于不能重复,所以用哈希的方式会非常复杂,所以采用双指针。要先排序再双指针

注意:先固定一个位置,左右指针是在该位置之后,剩余数组上的

代码

时间复杂度:O(n^2) 空间复杂度:O(1)

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

18. 四数之和

题目:18. 四数之和 - 力扣(LeetCode)

题解:代码随想录 (programmercarl.com)

状态:半AC

思路

注意:类似三指针,多套了一层循环

代码

时间复杂度:O(n^3) 空间复杂度:O(1)

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] > target && nums[i] >= 0) break;
            if(i > 0 && nums[i] == nums[i - 1]) continue;
            for(int j = i + 1; j < nums.length; j++){
                if(nums[i] + nums[j] > target && nums[i] + nums[j] >= 0) break;
                if(j > i + 1 && nums[j] == nums[j - 1]) continue;

                int left = j + 1, right = nums.length - 1;
                while(left < right){
                    int sum = nums[i] + nums[j] + nums[left] + nums[right];
                    if(sum == target){
                        res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                        while(left < right && nums[left] == nums[left + 1]) left++;
                        while(left < right && nums[right] == nums[right - 1]) right--;
                        left++;
                        right--;
                    }else if(sum > target){
                        right--;
                    }else{
                        left++;
                    }
                }
            }
        }

        return res;
    }
}