Skip to content

Instantly share code, notes, and snippets.

@jianminchen
Created December 27, 2016 07:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jianminchen/cbc62795cc5eca621c395a7a5dc3f6bd to your computer and use it in GitHub Desktop.
Save jianminchen/cbc62795cc5eca621c395a7a5dc3f6bd to your computer and use it in GitHub Desktop.
Leetcode 15 - 3 sum, using binary search, TLE error, but great workout using Array.BinarySearch method.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace _16_3Sum
{
/*
* Leetcode 15: 3 sum
* https://leetcode.com/problems/3sum/
*
* Review the algorithm on code review of stackexchange.com
* http://codereview.stackexchange.com/questions/37922/given-an-array-find-any-three-numbers-which-sum-to-zero?rq=1
*/
class Program
{
static void Main(string[] args)
{
ThreeSumTestCase();
}
private static void ThreeSumTestCase()
{
// 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);
} //
/*
* Dec. 26, 2016
* http://codereview.stackexchange.com/questions/37922/given-an-array-find-any-three-numbers-which-sum-to-zero?rq=1
*
* May 17, 2016
* Work on this 3 sum close algorithm
*
* 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)
*
* TLE - time limited exceeded
* O(n*n*logn)
*
* Best time complexity using two points - O(n*n)
*
* Warning: Do not use
* int[] searchArray = nums.Skip(j + 1).ToArray();
* The above statement will take O(n) time, n is size of the array
*
*
*/
public static IList<IList<int>> ThreeSum(int[] nums)
{
IList<IList<int>> results = new List<IList<int>>();
if (nums == null || nums.Length == 0)
return results;
Array.Sort(nums);
int len = nums.Length;
HashSet<string> foundNos = new HashSet<string>();
for (int i = 0; i < len - 2; i++) // len = 3, test case passes!
{
for(int j = i+1; j < len; j++)
{
//int[] searchArray = nums.Skip(j + 1).ToArray(); // O(n) -> make algorithm O(n*n*n)
int searchValue = -1 * (nums[i] + nums[j]);
int index = Array.BinarySearch(nums, j+1, len-j-1, searchValue); // O(logn)
if (index >= 0)
{
int[] numberAsc = new int[] { nums[i], nums[j], nums[index] };
string key = PrepareKey(numberAsc, ',');
if (foundNos.Contains(key))
continue;
foundNos.Add(key);
IList<int> threeNos = numberAsc.ToList();
results.Add(threeNos);
}
}
}
return results;
}
private static string PrepareKey(int[] numbers, char delimiter)
{
if(numbers == null || numbers.Length == 0)
return "";
string key = string.Empty;
for (int i = 0; i < numbers.Length; i++ )
{
key += numbers[i] + delimiter.ToString();
}
return key;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment