代码随想录训练营 Day07 - 哈希表(下)

简介: 代码随想录训练营 Day07 - 哈希表(下)

作业题


454. 四数相加 II


package jjn.carl.hashtable;
import java.util.HashMap;
import java.util.Map;
/**
 * @author Jiang Jining
 * @since 2023-07-04 21:33
 */
public class LeetCode454 {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        Map<Integer, Integer> map = new HashMap<>();
        int res = 0;
        for (int first : nums1) {
            for (int second : nums2) {
                map.put(first + second, map.getOrDefault(first + second, 0) + 1);
            }
        }
        for (int third : nums3) {
            for (int fourth : nums4) {
                res += map.getOrDefault(-third - fourth, 0);
            }
        }
        return res;
    }
    public static void main(String[] args) {
        int[] nums1 = new int[]{1, 2};
        int[] nums2 = new int[]{-2, -1};
        int[] nums3 = new int[]{-1, 2};
        int[] nums4 = new int[]{0, 2};
        int fourSumCount = new LeetCode454().fourSumCount(nums1, nums2, nums3, nums4);
        System.out.println("fourSumCount = " + fourSumCount);
    }
}


383. 赎金信

package jjn.carl.hashtable;
/**
 * @author Jiang Jining
 * @since 2023-07-04 21:45
 */
public class LeetCode383 {
    public boolean canConstruct(String ransomNote, String magazine) {
        int[] charCount = new int[26];
        for (char c : ransomNote.toCharArray()) {
            charCount[c - 'a']++;
        }
        for (char c : magazine.toCharArray()) {
            charCount[c - 'a']--;
        }
        for (int j : charCount) {
            if (j > 0) {
                return false;
            }
        }
        return true;
    }
    public static void main(String[] args) {
        String ransomNote = "aa", magazine = "aab";
        boolean canConstruct = new LeetCode383().canConstruct(ransomNote, magazine);
        System.out.println("canConstruct = " + canConstruct);
    }
}


15. 三数之和

package jjn.carl.hashtable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * @author Jiang Jining
 * @since 2023-07-04 22:13
 */
public class LeetCode15 {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> result = new ArrayList<>();
        for (int i = 0; i < nums.length - 2; i++) {
            if (nums[i] > 0) {
                return result;
            }
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            int left = i + 1, right = nums.length - 1;
            while (left < right) {
                if (nums[left] + nums[right] + nums[i] < 0) {
                    left++;
                } else if (nums[left] + nums[right] + nums[i] > 0) {
                    right--;
                } else {
                    result.add(List.of(nums[i], nums[left], nums[right]));
                    while (left < right && nums[right] == nums[right - 1]) {
                        right--;
                    }
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++;
                    }
                    left++;
                    right--;
                }
            }
        }
        return result;
    }
    public static void main(String[] args) {
        int[] nums = new int[]{-1, 0, 1, 2, -1, -4};
        List<List<Integer>> threeSum = new LeetCode15().threeSum(nums);
        System.out.println("Arrays.toString(threeSum) = " + threeSum.toString());
    }
}


18. 四数之和

package jjn.carl.hashtable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * @author Jiang Jining
 * @since 2023-07-04 23:10
 */
public class LeetCode18 {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        // 排序很关键,是双指针法的前提
        Arrays.sort(nums);
        long res = 0L;
        List<List<Integer>> result = new ArrayList<>();
        for (int i = 0; i < nums.length - 3; i++) {
            // target 可以为负数,负数相加会变得更小
            if (nums[i] > 0 && nums[i] > target && target >= 0) {
                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] == nums[j - 1]) {
                    continue;
                }
                int left = j + 1, right = nums.length - 1;
                while (left < right) {
                    // 防止加法越界
                    long cur = (long) nums[i] + (long) nums[j] + (long) nums[left] + (long) nums[right];
                    if (cur < target) {
                        left++;
                    } else if (cur > target) {
                        right--;
                    } else {
                        result.add(List.of(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--;
                    }
                }
            }
        }
        return result;
    }
    public static void main(String[] args) {
        int[] nums = new int[]{1, 0, -1, 0, -2, 2};
        int target = 0;
        List<List<Integer>> fourSum = new LeetCode18().fourSum(nums, target);
        System.out.println("fourSum = " + fourSum);
        // Case two
        nums = new int[]{2, 2, 2, 2, 2, 2};
        target = 8;
        fourSum = new LeetCode18().fourSum(nums, target);
        System.out.println("fourSum = " + fourSum);
        // 非常猥琐的测试用例
        nums = new int[]{1000000000, 1000000000, 1000000000, 1000000000};
        target = -294967296;
        fourSum = new LeetCode18().fourSum(nums, target);
        System.out.println("fourSum = " + fourSum);
    }
}


总结


  • 某些场景用数组非常合适,如只会有小写的字母等,采用哈希表速度可能不如数组快;输入的数据可能性没有限制,则只能用哈希表;
  • N 数之和,基本思路:确定左边的数,留下最后两个,用双指针不断收缩,求解答案,难点在于去重。

目录
相关文章
|
4月前
力扣面试经典题之哈希表
力扣面试经典题之哈希表
30 0
|
3月前
|
存储 算法 Java
面试高频算法题汇总「图文解析 + 教学视频 + 范例代码」之 二分 + 哈希表 + 堆 + 优先队列 合集
面试高频算法题汇总「图文解析 + 教学视频 + 范例代码」之 二分 + 哈希表 + 堆 + 优先队列 合集
|
11月前
|
存储 算法 Java
《代码随想录》刷题笔记——哈希表篇【java实现】
《代码随想录》刷题笔记——哈希表篇【java实现】
72 0
|
4月前
|
存储 机器学习/深度学习 算法
六六力扣刷题哈希表之三数之和
六六力扣刷题哈希表之三数之和
50 0
|
存储
代码随想录训练营 Day06 - 哈希表(上)
代码随想录训练营 Day06 - 哈希表(上)
46 0
数据结构一个小白的练级之路【链表的分割】题目参考
数据结构一个小白的练级之路【链表的分割】题目参考
|
算法
算法竞赛100天第四天 —— 设计哈希表(散列表)
算法竞赛100天第四天 —— 设计哈希表(散列表)
109 0
算法竞赛100天第四天 —— 设计哈希表(散列表)
|
存储 算法
代码随想录算法训练营第七天 | 哈希表
代码随想录算法训练营第七天 | 哈希表
120 0
|
存储 算法 索引
代码随想录算法训练营第六天 | 哈希表 四道简单题
代码随想录算法训练营第六天 | 哈希表 四道简单题
87 0
|
机器学习/深度学习 对象存储 索引
【代码随想录】第5章:哈希表
【代码随想录】第5章:哈希表
139 0
【代码随想录】第5章:哈希表