本文已参与「新人创作礼」活动,一起开启掘金创作之路
第454题.四数相加II
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。
为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -2^28 到 2^28 - 1 之间,最终结果不会超过 2^31 - 1 。
例如:
输入: A = [ 1, 2] B = [-2,-1] C = [-1, 2] D = [ 0, 2] 输出: 2 解释: 两个元组如下:
- (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
- (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
这题拿过来,是不是就想着和我一样四层循环
/**
* @param nums1
* @param nums2
* @param nums3
* @param nums4
* @return
* @Version 1.0
*/
public int fourSumCount1(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int count = 0;
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums1.length; j++) {
for (int k = 0; k < nums1.length; k++) {
for (int l = 0; l < nums1.length; l++) {
if (nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0) {
count++;
}
}
}
}
}
return count;
}
没有用的,不要把力扣当傻子,老老实实做题。 回想一下昨天做两数之和的时候,用的hashMap,直接把O(N^2^)转化为O(N) 这题也一样,前后两个数组分别相加 把O(N^4^)转化为O(N^2^)
/**
* @param nums1
* @param nums2
* @param nums3
* @param nums4
* @return
* @Version 2.0
*
* 1,1 0.2 -1.1
* -1 1 2 4
*/
public static int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
/**
* 可以类似两数之和。把O(N^4)转化为O(N^2),用两数之和思想
*/
//总数
int count = 0;
//数组长度
int n = nums1.length;
//结果集,键为需要的结果,值为键出现的次数,因为set中键唯一
HashMap<Integer, Integer> result = new HashMap<>();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
//set中键不重复
if (result.containsKey(-(nums1[i] + nums2[j]))) {
//如果键重复出现,要记录键出现的次数
int value = result.get(-(nums1[i] + nums2[j])) + 1;
result.put(-(nums1[i] + nums2[j]), value);
} else {
result.put(-(nums1[i] + nums2[j]), 1);
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (result.containsKey(nums3[i] + nums4[j])) {
//比如1 2 之和出现4次-1,3 4 之和 每出现1次1,则就加4次
count += result.get(nums3[i] + nums4[j]);
}
}
}
return count;
}
嚯嚯嚯!!! 看了一下题解,和我思路一模一样,只是改用了增强for,速度就上去好多
/**
* @param nums1
* @param nums2
* @param nums3
* @param nums4
* @return
* @Version 3.0
* 增强for改写一下
*
*/
public static int fourSumCount3(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
/**
* 可以类似两数之和。把O(N^4)转化为O(N^2),用两数之和思想
*/
//总数
int count = 0;
//数组长度
int n = nums1.length;
//结果集,键为需要的结果,值为键出现的次数,因为set中键唯一
HashMap<Integer, Integer> result = new HashMap<>();
for (int i:nums1) {
for (int j :nums2) {
//set中键不重复
if (result.containsKey(-(i + j))) {
//如果键重复出现,要记录键出现的次数
int value = result.get(-(i + j)) + 1;
result.put(-(i + j), value);
} else {
result.put(-(i + j), 1);
}
}
}
for (int i:nums3) {
for (int j :nums4) {
if (result.containsKey(i + j)) {
//比如1 2 之和出现4次-1,3 4 之和 每出现1次1,则就加4次
count += result.get(i + j);
}
}
}
return count;
}