public class Solution {
private int _len;
public IList<IList<int>> FourSum(int[] nums, int target) {
_len = nums.Length;
nums = nums.OrderBy(n => n).ToArray();
return KSum(nums, target, 4, 0);
}
private IList<IList<int>> KSum(int[] nums, int target, int k, int index)
{
var res = new List<IList<int>>();
if (index >= _len) return res;
if (k == 2)
{
int i = index, j = _len - 1;
while (i < j)
{
// Find a pair
if (target - nums[i] == nums[j])
{
res.Add(new List<int> { nums[i], target - nums[i] });
// Skip duplication
while (i < j && nums[i] == nums[i + 1]) i++;
while (i < j && nums[j - 1] == nums[j]) j--;
i++;
j--;
}
// Move left bound
else if (target - nums[i] > nums[j]) i++;
// Move right bound
else j--;
}
}
else
{
for (var i = index; i < _len - k + 1; i++)
{
// Use current number to reduce K Sum into K-1 Sum
var temp = KSum(nums, target - nums[i], k - 1, i + 1);
if (temp.Any())
{
// Add previous results
foreach (var t in temp)
{
t.Add(nums[i]);
}
res.AddRange(temp);
}
// Skip duplicated numbers
while (i < _len - 1 && nums[i] == nums[i + 1]) i++;
}
}
return res;
}
}
答案二:
public IList<IList<int>> FourSum(int[] nums, int target) {
var result = new List<IList<int>>();
var map = new Dictionary<int, List<IList<int>>>();
for(int i = 0; i < nums.Length; i++)
{
for(int j = i+1; j< nums.Length; j++)
{
int sum = nums[i] + nums[j];
var pair = new List<int>(){i,j};
if(map.ContainsKey(sum))
{
map[sum].Add(pair);
}
else
{
map.Add(sum, new List<IList<int>>() {pair});
}
}
}
var set = new HashSet<string>();
foreach(var key in map.Keys)
{
if(map.ContainsKey(target - key))
{
if(target - key == key && map[key].Count == 1)
{
continue;
}
foreach(var p1 in map[key])
{
foreach(var p2 in map[target-key])
{
if(p1.Contains(p2[0]) || p1.Contains(p2[1]) || p2.Contains(p1[0]) || p2.Contains(p1[1]))
{
continue;
}
var tempList = new List<int>();
tempList.Add(nums[p1[0]]);
tempList.Add(nums[p1[1]]);
tempList.Add(nums[p2[0]]);
tempList.Add(nums[p2[1]]);
tempList.Sort();
var checkKey = string.Join("", tempList.ToArray());
if(!set.Contains(checkKey))
{
result.Add(tempList);
set.Add(checkKey);
}
}
}
}
}
return result;
}