18.四数之和

题目描述:

  给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

  注意:

  答案中不可以包含重复的四元组。

  示例:

    给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

    满足要求的四元组集合为:
    [
      [-1, 0, 0, 1],
      [-2, -1, 1, 2],
      [-2, 0, 0, 2]
    ]

package array;

import java.util.ArrayList;
import java.util.List;

public class Leecode17 {

    public static List<List<Integer>> fourSum(int[] nums, int target)  {
        //首先需要进行排序
        quickSort(nums,0,nums.length-1);
        List<List<Integer>> returnList = new ArrayList<>();
        int minIndex = 0;
        //判断长度,如果长度小于4就直接返回
        if(nums.length<4){return returnList;}
        while(nums[minIndex] <= target/4 && minIndex<nums.length-1) {
            int maxIndex = nums.length - 1;
            //判断最小的数,是否与上一个重复
            if (minIndex > 0 && nums[minIndex] == nums[minIndex - 1]) {
                minIndex ++;
                continue;
            }
            while (nums[maxIndex] >= target/4 && (maxIndex - minIndex) > 2 && maxIndex > 2) {
                //判断最大的数,是否与上一个重复
                if (maxIndex != nums.length - 1 && nums[maxIndex] == nums[maxIndex + 1]) {
                    maxIndex --;
                    continue;
                }
                //选取左右指针,左指针为最小数的index+1,右指针为nums.length-1
                int right = maxIndex - 1, left = minIndex + 1;
                while (left < right) {
                    /*
                     *分为三种情况:
                     *   1、index的数与左右指针指的数之和为0,那么left++,right--;
                     *   2、之和小于0,那么其余两数之和需要增加,left++;
                     *   3、之和大于0,那么其余两数需要减少,right--;
                     * **/
                    if ((nums[left] + nums[right] + nums[minIndex] + nums[maxIndex]) == target) {
                        List<Integer> newList = new ArrayList<>();
                        newList.add(nums[minIndex]);newList.add(nums[left]);newList.add(nums[right]);newList.add(nums[maxIndex]);
                        returnList.add(newList);
                        //避免出现结果重复
                        while ((left < right) && nums[left + 1] == nums[left]) { left++; }
                        if (left++ == right) { break; }
                        while ((left < right) && nums[right - 1] == nums[right]) { right--; }
                        if (left == right--) { break; }
                    }
                    if ((nums[left] + nums[right] + nums[minIndex] + nums[maxIndex]) < target) {
                        while ((left < right) && nums[left + 1] == nums[left]) { left++; }
                        if (left++ == right) { break; }
                    }
                    if ((nums[left] + nums[right] + nums[minIndex] + nums[maxIndex]) > target) {
                        while ((left < right) && nums[right - 1] == nums[right]) { right--; }
                        if (left == right--) { break; }
                    }
                }
                maxIndex--;
            }
            minIndex++;
        }
        return returnList;

    }

    public static void quickSort(int[] nums, int start,int end){
        int i,j,temp;
        if(start >end){return;}
        temp = nums[start];i=start;j=end;
        while(i!=j){

            while(nums[j]>=temp && i<j){j--;}
            while(nums[i]<=temp && i<j){i++;}

            if(i<j){
                int t = nums[i];
                nums[i]= nums[j];
                nums[j] = t;
            }
        }
        nums[start] = nums[i];
        nums[i]=temp;
        quickSort(nums,start,i-1);
        quickSort(nums,i+1,end);

    }
    public static void main(String[] args) {

        int[] nums = {};
        List<List<Integer>> returnList = fourSum(nums,5);
        for(int index = 0;index<returnList.size();index++){
            for(int index2 = 0;index2<returnList.get(index).size();index2++){
                System.out.println(returnList.get(index).get(index2));
            }
        }



    }
}
原文地址:https://www.cnblogs.com/mayang2465/p/11723924.html