diff --git a/src/main/java/cn/whaifree/leetCode/Hash/LeetCode1.java b/src/main/java/cn/whaifree/leetCode/Hash/LeetCode1.java new file mode 100644 index 0000000..5fd65f1 --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Hash/LeetCode1.java @@ -0,0 +1,74 @@ +package cn.whaifree.leetCode.Hash; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * 1. 两数之和 + * + * 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 + * + * 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 + * + * 你可以按任意顺序返回答案。 + * + * 示例 1: + * + * 输入:nums = [2,7,11,15], target = 9 + * 输出:[0,1] + * 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。 + * 示例 2: + * + * 输入:nums = [3,2,4], target = 6 + * 输出:[1,2] + * 示例 3: + * + * 输入:nums = [3,3], target = 6 + * 输出:[0,1] + * + * + * 提示: + * + * 2 <= nums.length <= 104 + * -109 <= nums[i] <= 109 + * -109 <= target <= 109 + * 只会存在一个有效答案 + * + * + * 进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗? + */ +public class LeetCode1 { + + @Test + public void test() { + int[] ints = new Solution().twoSum(new int[]{1, 2, 3, 4}, 4); + for (int anInt : ints) { + System.out.println(anInt); + + } + } + + class Solution { + /** + * 时间复杂度 O(N) map.containsKey(key)的时间复杂度是O(1),因为Map的containsKey方法使用哈希表实现,可以在常数时间内判断Map中是否包含指定的键。 + * 空间复杂度 O(N) + * @param nums + * @param target + * @return + */ + public int[] twoSum(int[] nums, int target) { + HashMap map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + int key = target - nums[i]; + if (map.containsKey(key)) { + return new int[]{i, map.get(key)}; + }else { + map.put(nums[i], i); + } + } + return null; + } + } +} diff --git a/src/main/java/cn/whaifree/leetCode/Hash/LeetCode454.java b/src/main/java/cn/whaifree/leetCode/Hash/LeetCode454.java new file mode 100644 index 0000000..a5282c7 --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Hash/LeetCode454.java @@ -0,0 +1,105 @@ +package cn.whaifree.leetCode.Hash; + +import org.junit.Test; + +import java.util.HashMap; + +/** + * 给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: + * + * 0 <= i, j, k, l < n + * nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0 + * + * + * 示例 1: + * + * 输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2] + * 输出:2 + * 解释: + * 两个元组如下: + * 1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0 + * 2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0 + * 示例 2: + * + * 输入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0] + * 输出:1 + * + * + * 提示: + * + * n == nums1.length + * n == nums2.length + * n == nums3.length + * n == nums4.length + * 1 <= n <= 200 + * -228 <= nums1[i], nums2[i], nums3[i], nums4[i] <= 228 + */ +public class LeetCode454 { + @Test + public void test() { + //[1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2] + System.out.println(new Solution().fourSumCount( + new int[]{1, 2, 3}, + new int[]{-1, -2, -3}, + new int[]{-1, 2, -3}, + new int[]{0, 2, 3} + )); + + } + + + class Solution { + public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) { + HashMap map = new HashMap<>(); + for (int i = 0; i < nums1.length; i++) { + for (int j = 0; j < nums2.length; j++) { + if (map.get(nums1[i] + nums2[j]) == null) { + map.put(nums1[i] + nums2[j], 1); + } else { + map.put(nums1[i] + nums2[j], map.get(nums1[i] + nums2[j])+1); + } + } + } + map.forEach( + (k, v) -> System.out.println(k + "=" + v) + ); + + int res = 0; + for (int i = 0; i < nums3.length; i++) { + for (int j = 0; j < nums4.length; j++) { + int integer = nums3[i] + nums4[j]; + if (map.containsKey(-integer)) { + // 表示前两个数 和后两个数相加为0,即 nums1[i] + nums2[j] = -(nums3[i] + nums4[j]) + res += map.get(-integer); + } + } + } + return res; + } + } + + class Solution1 { + // 时间复杂度O(N2) + // 空间复杂度O(N) 在最坏的情况下,A[i]+B[j] 的值均不相同,因此也就需要 O(n^2) 的空间。 + //1 + public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) { + HashMap map = new HashMap<>(); + for (int i : nums1) { + for (int j : nums2) { + int sum = i + j; + map.put(sum, map.getOrDefault(sum, 0) + 1); + // getOrDefault 如果没有则用默认值。就不用使用Contain了 + } + } + + int res = 0; + for (int k : nums3) { + for (int i : nums4) { + int integer = k + i; + res += map.getOrDefault(- integer, 0); + } + } + return res; + } + } +}