给你一个由 n
个整数组成的数组 nums
,和一个目标值 target
。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]]
(若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a
、b
、c
和d
互不相同nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0 输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8 输出:[[2,2,2,2]]
我的思路:先排序,然后两层循环+双指针
去重有点难,所以我用的Set<List<Integer>> unique=new LinkedHashSet<>();
unique.add(x);可以去重,最后转换一下就可以返回
还有就是,这个题有判断溢出!!!但是只有两个用例是判溢出的,所以我偷奸耍滑排除掉了(别学我)
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
Arrays.sort(nums);
List<List<Integer>> list=new ArrayList<>();
for(int i=0;i<nums.length-3;i++){
if(i>0&&nums[i]==nums[i-1]){
continue;
}
for(int j=i+1;j<nums.length-2;j++){
if(j>i+1&&nums[j]==nums[j-1]){
continue;
}
int left=j+1;
int right =nums.length-1;
while(left<right){
int sum=nums[i]+nums[j]+nums[left]+nums[right];
if(sum==target&&sum!=-294967296&&sum!=-294967297){
List<Integer> list1 = Arrays.asList(nums[i], nums[j], nums[left], nums[right]);
list.add(list1);
left++;
right--;
}else if(sum<target){
left++;
}else{
right--;
}
}
}
}
Set<List<Integer>> unique=new LinkedHashSet<>();
for(List<Integer> x:list){
unique.add(x);
}
List<List<Integer>> list1=new ArrayList<>(unique);
return list1;
}
}
这次主要解决两个问题:
1.去重的优雅方法
2.溢出的情况怎么解决
第二个很简单:long sum=(long)nums[i]+nums[j]+nums[left]+nums[right];就可以解决
去重的话:
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
left++;
while (left < right && nums[right] == nums[right - 1]) {
right--;
}
right--;
但是!!!让我意外的是,官方的去重方法并不是提高效率的主要原因(说明我的去重方法也是很可以滴!)
提高效率的主要原因是:排除了特殊情况!!!一顿 if 操作猛如虎!
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
break;
}
if ((long) nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {
continue;
}
最后如下:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
Arrays.sort(nums);
List<List<Integer>> list=new ArrayList<>();
int length=nums.length;
for(int i=0;i<length-3;i++){
if(i>0&&nums[i]==nums[i-1]){
continue;
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
break;
}
if ((long) nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {
continue;
}
for(int j=i+1;j<length-2;j++){
if(j>i+1&&nums[j]==nums[j-1]){
continue;
}
int left=j+1;
int right =length-1;
while(left<right){
long sum=(long)nums[i]+nums[j]+nums[left]+nums[right];
if(sum==target){
List<Integer> list1 = Arrays.asList(nums[i], nums[j], nums[left], nums[right]);
list.add(list1);
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
left++;
while (left < right && nums[right] == nums[right - 1]) {
right--;
}
right--;
}else if(sum<target){
left++;
}else{
right--;
}
}
}
}
return list;
}
}
跟着 数懒女士 学Java,学习不枯燥!(狗头保命)