有很多問題討論旋轉字符串或確定一個字符串是否是另一個字符串的旋轉的最快/最佳方式。確定一個字符串在O(n)時間內有多少次旋轉與原始字符串匹配?
例如,忽略輸入消毒,你會看到something like this爲IsRotation:
public static bool IsRotation(string s1, string s2)
{
return (s1.Length == s2.Length && (s1 + s1).IndexOf(s2) != -1);
}
而且像這樣的東西旋轉:
public static string Rotate(string s, int index)
{
//Can't rotate. Return input.
if (s.Length < 2)
{
return s;
}
// Break input in half at rotation index
var s1 = s.Substring(0, index);
var s2 = s.Substring(index);
// Reverse the halves
var s1Reversed = Reverse(s1);
var s2Reversed = Reverse(s2);
// Join the reversed halves
var joined = s1Reversed + s2Reversed;
//Reverse and return the result.
var rotated = Reverse(joined);
return rotated;
}
例如,使用「富... 「 旋轉(」foo「,1)==」ofo「 - 和 - IsRotation(」foo「,」ofo「)== true;
我的問題是這些問題的延伸。
給定一個輸入字符串s,確定該字符串的旋轉次數與原始字符串相同。
考慮輸入字符串作爲旋轉,一些樣品輸入/輸出對:
IdenticalRotationCount("") == 1
IdenticalRotationCount("s") == 1
IdenticalRotationCount("sa") == 1
IdenticalRotationCount("ss") == 2
IdenticalRotationCount("ByeBye") == 2
IdenticalRotationCount("StackOverflow") == 0
我被告知存在將爲O運行(n)的時間的解決方案。初學者的解決方案是這樣的:
public static int IdenticalRotationCount(this string s)
{
//If length of s is less than two, we cannot rotate. Return 1.
if (s.Length < 2)
{
return 1;
}
//Get first char in s
var first = s[0];
//Consider input as first rotation that matches
var count = 1;
//Try each rotate position
for (var i = 1; i < s.Length; ++i)
{
var c = s[i];
//If current character doesn't start with same character as input
//we can skip the rotation
if (c != first)
{
continue;
}
//If the rotation at index i equals the input string, add 1 to result
if (StringExtensions.Rotate(s, i) == s)
{
++count;
}
}
return count;
}
但是,如果你選擇一個荒謬的輸入,像200000個連續的「一的,它會在相當一段時間運行。
任何人都可以提供運行在O(n)時間的解決方案嗎?在旋轉之前將輸入分成兩半時,我可以通過做實際比較來看到N^2,而不是做實際的旋轉,但看不到如何做O(n)。
謝謝!
PS - 如果有更合適的方式發佈這類問題,請在評論中說明。我很樂意移動它。
不應該IdenticalRotationCount(「StackOverflow」)== 1?因爲每個字符串都是自己的旋轉 – faisal 2013-05-03 00:03:47
@faisal - 好吧,不一定。但是夠公平的;我應該指定。 – 2013-05-29 19:29:40