---
# System prepended metadata

title: LC18 - 4Sum

---

# LC18 - 4Sum
# 双指针

```java=
class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        return kSum(nums, target, 4, 0);
    }

    private List<List<Integer>> kSum(int[] nums, int target, int k, int start) {
        
        int length = nums.length;
        if (k < 2 || length < k) {
            return new ArrayList<>();
        }

        if (k == 2) {
            return twoSum(nums, target, start);
        }
        
        List<List<Integer>> result = new ArrayList<>();
        for (int i = start; i < length; i++) {
            List<List<Integer>> subResult = kSum(nums, target - nums[i], k - 1, i + 1);
            for (List<Integer> temp: subResult) {
                temp.add(nums[i]);
                result.add(temp);
            }
            while (i < length - 1 && nums[i] == nums[i + 1]) {
                i++;
            }
        }
        
        return result;
    }

    private List<List<Integer>> twoSum(int[] nums, int target, int start) {
        List<List<Integer>> result = new ArrayList<>();

        int leftIdx = start;
        int rightIdx = nums.length - 1;

        while (leftIdx < rightIdx) {

            int leftVal = nums[leftIdx], rightVal = nums[rightIdx];
            int sum = leftVal + rightVal;
            int middleIdx = leftIdx + (rightIdx - leftIdx) / 2;
            int middleVal = nums[middleIdx];

            if (sum > target) { // shrink right bound
                if (leftVal + middleVal > target) {
                    rightIdx = middleIdx;
                    rightVal = middleVal;
                }
                while (leftIdx < rightIdx && rightVal == nums[rightIdx]) {
                    rightIdx--;
                }
            } else if (sum < target) { // shrink left bound
                if (middleVal + rightVal < target) {
                    leftIdx = middleIdx;
                    leftVal = middleVal;
                }
                while (leftIdx < rightIdx && leftVal == nums[leftIdx]) {
                    leftIdx++;
                }
            } else {
                List<Integer> temp = new ArrayList<>();
                temp.add(leftVal);
                temp.add(rightVal);
                result.add(temp);
                while (leftIdx < rightIdx && rightVal == nums[rightIdx]) {
                    rightIdx--;
                }
                while (leftIdx < rightIdx && leftVal == nums[leftIdx]) {
                    leftIdx++;
                }
            }
        }

        return result;
    }
}

```