面试题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)

posted @ 2015-12-31 03:36  橙喵moe  阅读(448)  评论(0编辑  收藏  举报