Created
January 9, 2017 07:21
-
-
Save jianminchen/483661b9d37f43ba0fa4de5374bd2415 to your computer and use it in GitHub Desktop.
Sherlock and anagram - code review - https://www.hackerrank.com/challenges/sherlock-and-anagrams - review on January 8, 2017
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; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace SherlockAndAnagrams | |
{ | |
class CharCount | |
{ | |
protected bool Equals(CharCount other) | |
{ | |
return Equals(Array, other.Array); | |
} | |
public override int GetHashCode() | |
{ | |
int hc = Array.Length; | |
for (int i = 0; i < Array.Length; ++i) | |
{ | |
hc = unchecked(hc * 13 + Array[i]); | |
} | |
return hc; | |
} | |
public readonly byte[] Array; | |
public CharCount() | |
{ | |
Array = new byte[26]; | |
} | |
public CharCount(CharCount charCount) | |
{ | |
Array = new byte[26]; | |
for (int i = 0; i < 26; i++) | |
{ | |
Array[i] = charCount.Array[i]; | |
} | |
} | |
public void AddChar(char ch) | |
{ | |
Array[ch - 'a']++; | |
} | |
public override bool Equals(object obj) | |
{ | |
CharCount other = obj as CharCount; | |
if (obj == null) | |
{ | |
return false; | |
} | |
for (int i = 0; i < 26; i++) | |
{ | |
int val = Array[i].CompareTo(other.Array[i]); | |
if (val != 0) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
RunSampleTestcase1(); | |
} | |
/* | |
* January 8, 2016 | |
* 1. abba, | |
Let's say S[i, j] denotes the substring(i, j-i+1) | |
S[0,1] = "ab", | |
S[0,2] ="abb", | |
S[1,1] = "b" | |
S[4,4] = "b" | |
S[1,2] = "ab" | |
S[3,4] = "ba" | |
For S = abba, anagrammatic pairs are: | |
{S[1,1], S[4,4]}, | |
{S[1,2], S[3,4]}, | |
{S{2,2], S{3,3]}, | |
{S[1,3], S[2,4]} | |
* Notice that substring can be selected by first char of string, choice of n-m, n is string length, m is substring length. | |
substrings can be overlapped, but still are anagrammatic pairs. | |
S[1,3] and S[2,4] are overlapped, but are the anagrammatic pair. | |
Sample test case "abba", output should be 4 | |
* | |
* Read editorial notes: | |
* Frequency table | |
* Time: O(N*N*26) | |
* | |
* Frequency table: | |
* | |
* We need to check if string S1 and S2 are anagrams, we first build frequency table where | |
* frequencies[i] stores the frequency of character i + a. If two strings have same frequency | |
* table they are anagrams. | |
* | |
* Approach 1: O(N^3 x 26) | |
* Traverse over all O(N x N) substrings and for each substring in O(N) build | |
* the frequency table and store after hashing. | |
* | |
* | |
* Approach 2: O(N^2 x 26) | |
* Starting for i = 1 to N, we dynamically build frequency for substring S[i,j] where j ranges | |
* from i to N. So, overall complexity here would be O(N^2 x 26). | |
* | |
* Current function uses approach ? | |
*/ | |
private static void RunSampleTestcase1() | |
{ | |
IDictionary<CharCount, int> dictionary = new Dictionary<CharCount, int>(); | |
string str = "abba"; | |
int length = str.Length; | |
for (int i = 0; i < length; i++) | |
{ | |
CharCount charCount = new CharCount(); | |
for (int j = i; j < length; j++) | |
{ | |
char current = str[j]; | |
charCount.AddChar(current); | |
if (!dictionary.ContainsKey(charCount)) | |
{ | |
dictionary.Add(new CharCount(charCount), 1); | |
} | |
else | |
{ | |
dictionary[charCount] = dictionary[charCount] + 1; | |
} | |
} | |
} | |
int result = dictionary.Values.Sum(value => ((value * (value - 1)) / 2)); | |
Debug.Assert(result == 4); | |
} | |
public static void ProcessInput() | |
{ | |
int t = int.Parse(Console.ReadLine()); | |
for (int i = 0; i < t; i++) | |
{ | |
HandleTestCase(); | |
} | |
} | |
private static void HandleTestCase() | |
{ | |
IDictionary<CharCount, int> dictionary = new Dictionary<CharCount, int>(); | |
string str = Console.ReadLine(); | |
for (int i = 0; i < str.Length; i++) | |
{ | |
CharCount charCount = new CharCount(); | |
for (int j = i; j < str.Length; j++) | |
{ | |
charCount.AddChar(str[j]); | |
if (!dictionary.ContainsKey(charCount)) | |
{ | |
dictionary.Add(new CharCount(charCount), 1); | |
} | |
else | |
{ | |
dictionary[charCount] = dictionary[charCount] + 1; | |
} | |
} | |
} | |
Console.WriteLine(dictionary.Values.Sum(value => ((value * (value - 1)) / 2))); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment