Created
October 25, 2017 17:21
-
-
Save jianminchen/de687a20b87fde1ee1cc17a43adb13b4 to your computer and use it in GitHub Desktop.
Get shortest unique substring - code review on the webpage: https://codereview.stackexchange.com/a/176779/123986
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace substring_practice | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var testResult = GetShortestUniqueSubstring(new char[] { 'a', 'b', 'c' }, "aefbcgaxy"); | |
Debug.Assert(testResult.CompareTo("bcga") == 0); | |
} | |
/// <summary> | |
/// Oct. 25, 2017 | |
/// code is reviewed on this webpage: | |
/// https://codereview.stackexchange.com/questions/176769/find-the-smallest-substring-that-contains-some-given-subset-of-characters | |
/// </summary> | |
/// <param name="search"></param> | |
/// <param name="source"></param> | |
/// <returns></returns> | |
public static string GetShortestUniqueSubstring(char[] search, string source) | |
{ | |
if (search == null || search.Length == 0) | |
{ | |
throw new ArgumentException("Search collection is null or empty.", "Search argument"); // code review 1 | |
} | |
// assume that search string is not empty | |
if (string.IsNullOrEmpty(source)) | |
{ | |
throw new ArgumentException("Source string in null or empty", "Source argument"); // code review 2 | |
} | |
// put unique chars in search string to the dictionary | |
var map = search.ToDictionary(c => c, c => 1); // code review 3 | |
var needChars = search.Length; // 'xyz' - 3, var match = needChars == 0 | |
// iterate the string and find match, and also keep track of minimum | |
var left = 0; | |
var length = source.Length; | |
var smallestLength = length + 1; | |
var smallestSubstring = ""; | |
for (int index = 0; index < length; index++) | |
{ | |
var visit = source[index]; | |
//TryGetValue method to avoid double search of the value by key. | |
int count; // code review | |
var inMap = map.TryGetValue(visit, out count); // code review 4 | |
var needOne = inMap && count > 0; | |
if (inMap) | |
{ | |
map[visit]--; | |
} | |
if (needOne) | |
{ | |
needChars--; | |
} | |
var findMatch = needChars == 0; | |
if (!findMatch) | |
{ | |
continue; | |
} | |
// move left point forward - while loop | |
while (left <= index && (!map.ContainsKey(source[left]) || (map[source[left]] < 0))) // code review 5 | |
{ | |
var removeChar = source[left]; | |
// update the variable needChars | |
if (map.ContainsKey(source[left])) | |
{ | |
map[removeChar]++; | |
} | |
left++; | |
} | |
var currentLength = index - left + 1; | |
var findSmallerOne = currentLength < smallestLength; | |
if (findSmallerOne) | |
{ | |
smallestLength = currentLength; | |
smallestSubstring = source.Substring(left, currentLength); | |
needChars++; | |
map[source[left]]++; | |
left = left + 1; | |
} | |
} | |
// edge case | |
return smallestLength == length + 1 // code review 6 | |
? string.Empty | |
: smallestSubstring; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment