代码随想录-2023/07/06

90 阅读1分钟

哈希表

四数相加II

  1. 暴力法:四重for循环
  2. 哈希表: 先用两层for循环将两个数组中的元素和记录在哈希表中, 然后再将另外两个数组用for循环遍历, 求其和的负数是否在哈希表中, 记录个数

代码:

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int n = nums1.length;
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                int sum = nums1[i] + nums2[j];
                map.put(sum, map.getOrDefault(sum, 0) + 1);
            }
        }
        int ans = 0;
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                int sum = nums3[i] + nums4[j];
                if(map.containsKey(-sum)){
                    ans += map.get(-sum);
                }
            }
        }

        return ans;
    }
}

383 赎金信

  1. 先统计 ransomNote 里面的字符个数, 记录在哈希表中
  2. 然后遍历 magazine, 如果哈希表中有, 就将其个数-1
  3. 最后再遍历哈希表, 若里面字符个数 > 0, 则代表不够组成 ransomNote, 返回false
class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        HashMap<Character, Integer> map = new HashMap<>();
        for(int i=0; i<ransomNote.length(); i++){
            char c = ransomNote.charAt(i);
            map.put(c, map.getOrDefault(c, 0) + 1);
        }

        for(int i=0; i<magazine.length(); i++){
            char c = magazine.charAt(i);
            if(map.containsKey(c)){
                map.put(c, map.get(c) - 1);
            }  
        }

        for(char c : map.keySet()){
            if(map.get(c) > 0) return false;
        }

        return true;
    }
}

15.三数之和

排序+双指针法

先排序,然后固定一个数,另外两个数用双指针寻找

代码:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> list = new ArrayList<>();
        for(int i=0; i<nums.length && nums[i] <= 0; i++){
            // 去重
            if(i > 0 && nums[i] == nums[i-1]) continue;
            int l = i + 1, r = nums.length - 1;
            while(l < r) {
                int sum = nums[i] + nums[l] + nums[r];
                if(sum < 0) {
                    l++;
                }else if(sum > 0) {
                    r--;
                }else {
                    list.add(Arrays.asList(nums[i], nums[l], nums[r]));
                    while(l < r && nums[l] == nums[l+1]) l++;
                    while(l < r && nums[r] == nums[r-1]) r--;
                     // 移动双指针
                    l++; r--;
                }
               
            }
        }
        return list;
    }
}

18.四数之和

  1. 参照三数之和
  2. 用两层for循环固定两个数字
  3. 然后其余两个数字用双指针寻找, 用排序+双指针替代两个for循环
  4. 注意对 i,j,l,r 的去重

代码:

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> list = new ArrayList<>();
        for(int i=0; i<nums.length; i++){
            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(l < r) {
                    long sum = (long)nums[i] + nums[j] + nums[l] + nums[r];
                    if(sum < target) l++;
                    else if(sum > target) r--;
                    else {
                        list.add(Arrays.asList(nums[i], nums[j], nums[l], nums[r]));
                        while(l < r && nums[l] == nums[l+1]) l++;
                        while(l < r && nums[r] == nums[r-1]) r--;
                        l++; r--;  
                    }
                }
            }
        }
        return list;
    }
}