剑指offer 58 - 左旋转字符串

30 阅读1分钟

剑指 Offer 58 - II. 左旋转字符串

题意:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。

比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例

输入: s = "abcdefg", k = 2

输出: "cdefgab"


  1. 算法题目中,字符串拼接优先使用StringBuilder
  2. 字符串的长度为s.length();

方案1-字符串拼接

public String reverseLeftWords(String s, int n) {
  StringBuilder sb = new StringBuilder();
  for(int i = n; i < s.length();i++){
    sb.append(s.charAt(i));
  }
  
  for(int i = 0;i < n;i ++){
    sb.append(s.charAt(i));
  }
  
  return sb.toString();
}

方案2-取余操作

public String reverseLeftWords(String s, int n) {
  int length = s.length();
  
  StringBuilder sb = new StringBuilder();
  
  for(int i = n; i < n +length; i++){
    sb.append(s.charAt(i%length));  
  }
  return sb.toString();
}

最优解

对于旋转类的题目,首先我们要分清方向:左 or 右

然后就是3次翻转操作,2次局部翻转,1次整体翻转。

1.向左旋转

  1. 先翻转前半部分;
  2. 再翻转后半部分;
  3. 整体翻转;

2. 向右旋转

  1. 先翻转后半部分;
  2. 再翻转前半部分;
  3. 整体翻转;
public String reverseLeftWords(String s, int n){
  char[] cs = s.toCharArray();
  int length = cs.length;
  // 2次局部翻转
  reverse(cs,0,n-1);
  reverse(cs,n,length-1);
  // 1次整体翻转
  reverse(cs,0,length-1);
  
  return new String(cs);
}


public void reverse(char[] cs, int start, int end){
  while(start <= end){
    char tmp = cs[start];
    cs[start] = cs[end];
    cs[end] = tmp;
    
    start++;
    end--;
  }
}