454
This commit is contained in:
whai 2024-01-02 22:04:25 +08:00
parent c7ed23b029
commit 8490fdfcf7
2 changed files with 179 additions and 0 deletions

View File

@ -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<Integer, Integer> 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;
}
}
}

View File

@ -0,0 +1,105 @@
package cn.whaifree.leetCode.Hash;
import org.junit.Test;
import java.util.HashMap;
/**
* 给你四个整数数组 nums1nums2nums3 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<Integer, Integer> 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<Integer, Integer> 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;
}
}
}