面试题8 判断一个 String 是不是另一个 String 旋转而来
题目: 此题假设已经有一个方法 叫 isSubstring 判断一个 String 是不是另一个 String 的子 String, 现在要写一个方法 仅使用一次 isSubstring 方法去判断一个 String 是不是另一个 String 的 rotation, 也就是说 可不可以通过把 第二个 String 向右移动若干位而得到 第一个 String, 比如 abcde 就是 cdeab 向右旋转2位而来 那么该方法就应该返回true 相反如果是 abcde 和 abced 就不行 应该返回 false
思路是 如果两个 String 分别是 str1 和 str2 则, 如果 str1 是 str2 的旋转, 那么 str2 应该是 str1str1 的子 String. 比如, str1 = abcde 和 str2 = cdeab 那么 str1str1 = abcdeabcde 而且 str2 必须是 str1str1 的子 String
在进一步呢想 其实 只需要找到 str1 中第一个和 str2 中首字母相同的字母 然后将在那之前的所有字符添加到 str1 末尾 那么 str2 必须是所得字符串的子字符串
代码如下
public boolean mySolution(String str1, String str2){ if(str1.length()!=str2.length()) return false; int firstOccur = str1.indexOf(str2.charAt(0)); if(firstOccur<0) return false; else if(firstOccur==0) return str1.equals(str2); String s = str1.substring(0,firstOccur); return isSubstring(str1+s, str2); } public boolean isSubstring(String str1, String str2){ if(str1==null && str2==null) return true; if(str1==null || str2==null) return false; if(str1.length()==str2.length()) return str1.equals(str2); if(str1.length()<str2.length()) return isSubstring(str2, str1); int str1Length = str1.length(); int str2Length = str2.length(); char firstChar = str2.charAt(0); int currentFirst = str1.indexOf(firstChar); while(currentFirst<=str1Length-str2Length && currentFirst>0){ for(int j=currentFirst, k=0; k<str2Length; j++, k++){ if(str1.charAt(j)!=str2.charAt(k)) break; if(k>=str2Length-1) return true; } if(currentFirst<str1Length-1) currentFirst = str1.indexOf(firstChar, currentFirst+1); else break; } return false; }
其中 isSubstring 是使用暴力枚举法判断一个字符串是否是另一个的子字符串 假设 isSubstring 运行时间是 O(1) (题中并没有给出 isSubstring 方法 现在将此方法看成黑盒子) 那么该方法的时间复杂度是 O(n) 空间复杂度是 O(n)