-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path4Sum.java
More file actions
86 lines (82 loc) · 2.69 KB
/
Copy path4Sum.java
File metadata and controls
86 lines (82 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note: The solution set must not contain duplicate quadruplets.
For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0.
A solution set is:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]*/
public List<List<Integer>> fourSum(int[] nums, int target){
ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();
int len = nums.length;
if(nums == null || len < 4)
return res;
Arrays.sort(nums);
int max = nums[len - 1];
if(4 * nums[0] > target || 4 * max < target)
return res;
int i, z;
for(i = 0; i < len; i++){
z = nums[i];
if(i > 0 && z == nums[i - 1]) continue;//avoid duplicate
if(z + 3 * max < target) continue;//z is too small
if(4 * z > target) break;
if(4 * z == target){//z is the boundary
if(i + 3 < len && nums[i + 3] == z)
res.add(Arrays.asList(z, z, z, z));
break;
}
threeSumForFourSum(nums, target - z, i + 1, len - 1, res, z);
}
return res;
}
/*
Find all posible distinguished three numbers adding up to the target in sorted array nums[] between indices low and high. If there are, add all of them into the ArrayList fourSumList, using fourSumList.add(Arrays.asList(z1, the three numbers))
*/
public void threeSumForFourSum(int[] nums, int target, int low, int high, ArrayList<List<Integer>> fourSumList, int z1){
if(low + 1 >= high)
return;
int max = nums[high];
if(3 * nums[low] > target || 3 * max < target)
return;
int i, z;
for(i = low; i < high - 1; i++){
z = nums[i];
if(i > low && z == nums[i - 1])
continue;
if(z + 2 * max < target)
continue;
if(3 * z > target)
break;
if(3 * z == target){
if(i + 1 < high && nums[i + 2] == z)
fourSumList.add(Arrays.asList(z1, z, z, z));
break;
}
twoSumForFourSum(nums, target - z, i + 1, high, fourSumList, z1, z);
}
}
/*
Find all posible distinguished two numbers adding up to the target in sorted array nums[] between indices low and high. If there are, add all of them into the ArrayList fourSumList, using fourSumList.add(Arrays.asList(z1, z2, the two numbers)).
*/
public void twoSumForFourSum(int[] nums, int target, int low, int high, ArrayList<List<Integer>> fourSumList, int z1, int z2){
if(low >= high)
return;
if(2 * nums[low] > target || 2 * nums[high] < target)
return;
int i = low, j = high, sum, x;
while(i < j){
sum = nums[i] + nums[j];
if(sum == target){
fourSumList.add(Arrays.asList(z1, z2, nums[i], nums[j]));
x = nums[i];
while(++i < j && x == nums[i]);
x = nums[j];
while(i < --j && x == nums[j]);
}
if(sum < target) i++;
if(sum > target) j--;
}
return;
}