Given an array
S
ofn
integers, are there elementsa
,b
,c
inS
such thata + b + c = 0
? Find all unique triplets in the array which gives the sum of zero.Note: The solution set must not contain duplicate triplets.
For example, given array
S = [-1, 0, 1, 2, -1, -4]
, a solution set is:[ [-1, 0, 1], [-1, -1, 2] ]
I did review Leetcode 3 sum algorithm a few hours, and put together the following C# code. The time complexity is optimal, \$O(n*n)\$ where \$n\$ is the length of the array, pass Leetcode online judge. Also, I did a few improvements, make it more flat (using two continue statements, instead of if
/else
statements), test cases are added, two sum algorithm uses two pointer technique to go through the array once.
Please share your ideas to improve C# code.
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Leetcode_15_3Sum { /* * * Work on this 3 sum algorithm * * Leetcode 15: 3 sum * https://leetcode.com/problems/3sum/ * * Given an array S of n integers, are there elements a, b, c in S * such that a + b + c = 0? Find all unique triplets in the array * which gives the sum of zero. * Note: Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c) The solution set must not contain duplicate triplets. * For example, given array S = {-1 0 1 2 -1 -4}, A solution set is: (-1, 0, 1) (-1, -1, 2) * */ class Program { static void Main(string[] args) { // test 3 sum // 2 lists, one is -1, 0, 1, second one is -1, -1, 2 int[] array = new int[6] { -1, 0, 1, 2, -1, -4 }; IList<IList<int>> triplets = ThreeSum(array); Debug.Assert(triplets.Count == 2); Debug.Assert(String.Join(",", triplets[0].ToArray()).CompareTo("-1,-1,2") == 0); Debug.Assert(String.Join(",", triplets[1].ToArray()).CompareTo("-1,0,1") == 0); } /* * @nums - the array containing the numbers * * 3 sum can be solved using 2 sum algorithm, * 2 sum algorithm - optimal solution is using two pointers, time complexity is O(nlogn), * sorting takes O(nlogn), and two pointer algorithm is O(n), so overall is O(nlogn). * Time complexity for 3 sum algorithm: * O(n*n) */ public static IList<IList<int>> ThreeSum(int[] nums) { IList<IList<int>> results = new List<IList<int>>(); HashSet<string> keys = new HashSet<string>(); if (nums == null || nums.Length == 0) return results; Array.Sort(nums); int length = nums.Length; int target = 0; for (int i = 0; i < length - 2; i++) { int firstNo = nums[i]; // using two pointers to go through once the array, find two sum value int newTarget = target - firstNo; int start = i + 1; int end = length - 1; while (start < end) { int twoSum = nums[start] + nums[end]; if (twoSum < newTarget) { start++; continue; } if (twoSum > newTarget) { end--; continue; } int[] threeNumbers = new int[] { firstNo, nums[start], nums[end] }; string key = PrepareKey(threeNumbers, 3); if (!keys.Contains(key)) { keys.Add(key); results.Add(threeNumbers.ToList()); } // continue to search start++; end--; } } return results; } /* * -1, 0, 1 -> key string" "-1,0,1," */ private static string PrepareKey(int[] arr, int length) { string key = string.Empty; for (int j = 0; j < length; j++) { key += arr[j].ToString(); key += ","; } return key; } } }
[-1, 0, 1],
and[1, 0, -1],
considered duplicates ?\$\endgroup\$