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> FourSum(int[] nums, int target) { var dict = new Dictionary(); // суммы из двух слагаемых, все возможные var twoSums = new Dictionary>(); 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()); twoSums[sum].Add(new TwoSumSource() { A = num1, B = num2 }); } } var rows = new HashSet(); // словарь для требуемоего количества чисел var needDict = new Dictionary(); 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>(rows.Count); foreach (var row in rows) answer.Add(new List { row.N0!.Value, row.N1!.Value, row.N2!.Value, row.N3!.Value }); return answer; } }