18. 4Sum
This commit is contained in:
143
18. 4Sum/Solution.cs
Normal file
143
18. 4Sum/Solution.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
|
||||
public class Solution
|
||||
{
|
||||
record struct TwoSumSource(int A, int B)
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
return $"({A}+{B}={A + B})";
|
||||
}
|
||||
}
|
||||
|
||||
record struct AnswerRow(int? N0 = null, int? N1 = null, int? N2 = null, int? N3 = null)
|
||||
{
|
||||
|
||||
public void PushNum(int num)
|
||||
{
|
||||
if (N0 == null)
|
||||
{
|
||||
N0 = num;
|
||||
}
|
||||
else if (N1 == null)
|
||||
{
|
||||
N1 = num;
|
||||
if (N0 > N1)
|
||||
{
|
||||
(N0, N1) = (N1, N0);
|
||||
}
|
||||
}
|
||||
else if (N2 == null)
|
||||
{
|
||||
N2 = num;
|
||||
if (N1 > N2)
|
||||
{
|
||||
(N1, N2) = (N2, N1);
|
||||
}
|
||||
if (N0 > N1)
|
||||
{
|
||||
(N0, N1) = (N1, N0);
|
||||
}
|
||||
}
|
||||
else if (N3 == null)
|
||||
{
|
||||
N3 = num;
|
||||
if (N2 > N3)
|
||||
{
|
||||
(N2, N3) = (N3, N2);
|
||||
}
|
||||
if (N1 > N2)
|
||||
{
|
||||
(N1, N2) = (N2, N1);
|
||||
}
|
||||
if (N0 > N1)
|
||||
{
|
||||
(N0, N1) = (N1, N0);
|
||||
}
|
||||
}
|
||||
else if (num < N3)
|
||||
{
|
||||
N3 = num;
|
||||
if (N2 > N3)
|
||||
{
|
||||
(N2, N3) = (N3, N2);
|
||||
}
|
||||
if (N1 > N2)
|
||||
{
|
||||
(N1, N2) = (N2, N1);
|
||||
}
|
||||
if (N0 > N1)
|
||||
{
|
||||
(N0, N1) = (N1, N0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IList<IList<int>> FourSum(int[] nums, int target)
|
||||
{
|
||||
var dict = new Dictionary<int, int>();
|
||||
// суммы из двух слагаемых, все возможные
|
||||
var twoSums = new Dictionary<long, HashSet<TwoSumSource>>();
|
||||
for (var i = 0; i < nums.Length; i++)
|
||||
{
|
||||
var num1 = nums[i];
|
||||
dict.TryAdd(num1, 0);
|
||||
dict[num1]++;
|
||||
for (var j = i + 1; j < nums.Length; j++)
|
||||
{
|
||||
var num2 = nums[j];
|
||||
var sum = num1 + num2;
|
||||
twoSums.TryAdd(sum, new HashSet<TwoSumSource>());
|
||||
twoSums[sum].Add(new TwoSumSource() { A = num1, B = num2 });
|
||||
}
|
||||
}
|
||||
|
||||
var rows = new HashSet<AnswerRow>();
|
||||
// словарь для требуемоего количества чисел
|
||||
var needDict = new Dictionary<int, int>();
|
||||
foreach (var kp1 in dict)
|
||||
{
|
||||
var needThreeSum = target - kp1.Key;
|
||||
needDict.TryAdd(kp1.Key, 0);
|
||||
needDict[kp1.Key]++;
|
||||
foreach (var kp2 in dict)
|
||||
{
|
||||
needDict.TryAdd(kp2.Key, 0);
|
||||
needDict[kp2.Key]++;
|
||||
|
||||
var needTwoSum = (long)needThreeSum - kp2.Key;
|
||||
if (twoSums.TryGetValue(needTwoSum, out var curTwoSums))
|
||||
{
|
||||
foreach (var curTwoSum in curTwoSums)
|
||||
{
|
||||
needDict.TryAdd(curTwoSum.A, 0);
|
||||
needDict[curTwoSum.A]++;
|
||||
|
||||
needDict.TryAdd(curTwoSum.B, 0);
|
||||
needDict[curTwoSum.B]++;
|
||||
|
||||
if (needDict.All(kp => dict[kp.Key] >= kp.Value))
|
||||
{
|
||||
var row = new AnswerRow();
|
||||
row.PushNum(kp1.Key);
|
||||
row.PushNum(kp2.Key);
|
||||
row.PushNum(curTwoSum.A);
|
||||
row.PushNum(curTwoSum.B);
|
||||
rows.Add(row);
|
||||
}
|
||||
|
||||
needDict[curTwoSum.A]--;
|
||||
needDict[curTwoSum.B]--;
|
||||
}
|
||||
}
|
||||
needDict[kp2.Key]--;
|
||||
}
|
||||
needDict.Clear();
|
||||
}
|
||||
var answer = new List<IList<int>>(rows.Count);
|
||||
foreach (var row in rows)
|
||||
answer.Add(new List<int> { row.N0!.Value, row.N1!.Value, row.N2!.Value, row.N3!.Value });
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user