//给定一个包含 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]
//]
// 
// Related Topics 数组 哈希表 双指针 
// 👍 758 👎 0

/*
* 18 四数之和
* 2021-02-26 12:51:32
* @author oxygenbytes
*/ 
#include "leetcode.h" 
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public:
    vector<vector<int>> ans;
    vector<vector<int>> fourSum(vector<int>& nums, int target) {

        sort(nums.begin(), nums.end());
        int n = nums.size();
        if(n < 4 || nums[0] > 0 || nums[n-1] < 0) return ans;
        // for(auto x : nums) cout<<x<<" ";
        for(int i = 0;i <= n - 3;i++){
            if(i >= 1 && nums[i] == nums[i-1]) continue;

            for(int j = i + 1;j <= n - 2;j++){
                if(j > i + 1 && nums[j] == nums[j-1]) continue;

                int l = j + 1;
                int r = n - 1;
                int cur_sum = nums[i] + nums[j];
                while(l < r){
                    // cout<<i<<" "<<j<<" "<<l<<" "<<r<<endl;
                    int sum = cur_sum + nums[l] + nums[r];
                    if(sum < target)
                        l++;
                    else if(sum > target)
                        r--;
                    else{
                        ans.push_back({nums[i], nums[j], nums[l], nums[r]});
                        while( (l + 1) < n && nums[l] == nums[l+1]) l++;
                        l++;
                        while( (r - 1) >= 0 && nums[r] == nums[r-1]) r--;
                        r--;
                    }
                }
            }
        }
        return ans;
    }
};
//leetcode submit region end(Prohibit modification and deletion)