Question:
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.
方法一:与3Sum类似,先对数组排序,固定两个数字,再用夹逼法来找出其余两个数字。此方法的时间复杂度为o(n^3)
java代码如下:
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList();
for(int i = 0; i < nums.length; i ++){ // 排序
for(int j = i + 1; j < nums.length; j ++){
if(nums[i] > nums[j]){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
for(int i = 0; i < nums.length - 3; i ++){
for(int j = i + 1; j < nums.length - 2; j ++){
int temp = target - nums[i] - nums[j]; //固定两个数字在位置i ,j
int l = j + 1, h = nums.length - 1;
while(l < h){ //从j + 1开始,夹逼法
if(nums[l] + nums[h] == temp){
List<Integer> sol = new ArrayList();
sol.add(nums[i]);
sol.add(nums[j]);
sol.add(nums[l]);
sol.add(nums[h]);
res.add(sol);
l ++;
h --;
while(l < h && nums[l] == nums[l-1]) //注意不可以有重复的结果
l ++;
while(l < h && nums[h] == nums[h+1])
h --;
}
else if(nums[l] + nums[h] < temp)
l ++;
else
h --;
}
while(nums[j] == nums[j+1] && j < nums.length - 2)
j ++;
}
while(nums[i] == nums[i+1] && i < nums.length - 3)
i ++;
}
return res;
}
}
方法二:利用hashmap存储每对数字的和,接着固定一组数字的和,找到其余的一组数字,注意要去除重复的结果。时间复杂度为o(nlogn)
java代码如下:
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList();
for(int i = 0; i < nums.length; i ++){ //排序
for(int j = i + 1; j < nums.length; j ++){
if(nums[i] > nums[j]){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
HashMap<Integer, List<Integer[]>> map = new HashMap(); //用hashmap存储每两个数字的和
for(int i = 0; i < nums.length - 1; i ++){
for(int j = i + 1; j < nums.length; j ++){
int sum = nums[i] + nums[j];
Integer value[] = {nums[i], i, nums[j], j};
if(!map.containsKey(sum)){
map.put(sum, new ArrayList<Integer[]>());
}
map.get(sum).add(value);
}
}
Integer[] keys = map.keySet().toArray(new Integer[map.size()]); //固定一组数字,找出另一组数字
for(int key : keys){
if(map.containsKey(key)){
if(map.containsKey(target - key)){
List<Integer[]> fList = map.get(key);
List<Integer[]> sList = map.get(target - key);
for(int i = 0; i < fList.size(); i ++){
Integer[] first = fList.get(i);
for(int j = 0; j < sList.size(); j ++){
Integer[] second = sList.get(j);
if(first[1] != second[1] && first[1] != second[3] && first[3] != second[1] && first[3] != second[3]){ //避免相同的数字
List<Integer> ans = new ArrayList();
ans.add(first[0]); ans.add(first[2]); ans.add(second[0]); ans.add(second[2]);
Collections.sort(ans);
if(!res.contains(ans)){ //避免重复结果
res.add(ans);
}
}
}
}
map.remove(key);
map.remove(target - key);
}
}
}
return res;
}
}
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.
方法一:与3Sum类似,先对数组排序,固定两个数字,再用夹逼法来找出其余两个数字。此方法的时间复杂度为o(n^3)
java代码如下:
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList();
for(int i = 0; i < nums.length; i ++){ // 排序
for(int j = i + 1; j < nums.length; j ++){
if(nums[i] > nums[j]){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
for(int i = 0; i < nums.length - 3; i ++){
for(int j = i + 1; j < nums.length - 2; j ++){
int temp = target - nums[i] - nums[j]; //固定两个数字在位置i ,j
int l = j + 1, h = nums.length - 1;
while(l < h){ //从j + 1开始,夹逼法
if(nums[l] + nums[h] == temp){
List<Integer> sol = new ArrayList();
sol.add(nums[i]);
sol.add(nums[j]);
sol.add(nums[l]);
sol.add(nums[h]);
res.add(sol);
l ++;
h --;
while(l < h && nums[l] == nums[l-1]) //注意不可以有重复的结果
l ++;
while(l < h && nums[h] == nums[h+1])
h --;
}
else if(nums[l] + nums[h] < temp)
l ++;
else
h --;
}
while(nums[j] == nums[j+1] && j < nums.length - 2)
j ++;
}
while(nums[i] == nums[i+1] && i < nums.length - 3)
i ++;
}
return res;
}
}
方法二:利用hashmap存储每对数字的和,接着固定一组数字的和,找到其余的一组数字,注意要去除重复的结果。时间复杂度为o(nlogn)
java代码如下:
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList();
for(int i = 0; i < nums.length; i ++){ //排序
for(int j = i + 1; j < nums.length; j ++){
if(nums[i] > nums[j]){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
HashMap<Integer, List<Integer[]>> map = new HashMap(); //用hashmap存储每两个数字的和
for(int i = 0; i < nums.length - 1; i ++){
for(int j = i + 1; j < nums.length; j ++){
int sum = nums[i] + nums[j];
Integer value[] = {nums[i], i, nums[j], j};
if(!map.containsKey(sum)){
map.put(sum, new ArrayList<Integer[]>());
}
map.get(sum).add(value);
}
}
Integer[] keys = map.keySet().toArray(new Integer[map.size()]); //固定一组数字,找出另一组数字
for(int key : keys){
if(map.containsKey(key)){
if(map.containsKey(target - key)){
List<Integer[]> fList = map.get(key);
List<Integer[]> sList = map.get(target - key);
for(int i = 0; i < fList.size(); i ++){
Integer[] first = fList.get(i);
for(int j = 0; j < sList.size(); j ++){
Integer[] second = sList.get(j);
if(first[1] != second[1] && first[1] != second[3] && first[3] != second[1] && first[3] != second[3]){ //避免相同的数字
List<Integer> ans = new ArrayList();
ans.add(first[0]); ans.add(first[2]); ans.add(second[0]); ans.add(second[2]);
Collections.sort(ans);
if(!res.contains(ans)){ //避免重复结果
res.add(ans);
}
}
}
}
map.remove(key);
map.remove(target - key);
}
}
}
return res;
}
}