左旋转字符
每天一道算法题
题目:
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列 S ,请你把其循环左移 K 位后的序列输出。例如,字符序列 S = ”abcXYZdef” , 要求输出循环左移 3 位后的结果,即 “XYZdefabc”
也可以这样理解:将字符串 S 从第 K 位置分隔成两个子字符串,并交换这两个子字符串的位置。但是此处的k是上面的k对字符串长度取余。
方法一:三次翻转
方法二:二次遍历
/*
* 问题:
* 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,
* 就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列 S ,
* 请你把其循环左移 K 位后的序列输出。
* 例如,字符序列 S = ”abcXYZdef” , 要求输出循环左移 3 位后的结果,即 “XYZdefabc”
*/
public class Exer4 {
public static void main(String[] args) {
String str = "abcXYZdef";
int n = 6;
Solution4 solution4 = new Solution4();
System.out.println(solution4.LeftRotateString(str, n));
System.out.println(solution4.LeftRotateString_2(str, n));
}
}
class Solution4{
/*
* 方法一:用翻转。
* 其实这个问题也可理解为:将字符串 S 从第 K 位置分隔成两个子字符串,并交换这两个子字符串的位置。
* 这样就可以先分别把第一部分字符串翻转、第二部分字符串翻转,然后再把整体的字符串翻转
*
*/
public String LeftRotateString(String str,int n) {
int len = str.length();
int m = n % len;//按照题目的意思,n有可能大于string的长度,所以应该要取余
char[] c = str.toCharArray();//转换成字符数组
ReverseString(c, 0, m - 1);
ReverseString(c, m, len - 1);
ReverseString(c, 0, len - 1);
return new String(c);
}
/*
* 方法二:遍历拼接。顾名思义,把字符串遍历一下,先遍历后面的加入新的字符串,再遍历前面的加入
*
*/
public String LeftRotateString_2(String str, int n) {
int len = str.length();
int m = n % len;
StringBuilder sb = new StringBuilder();
for(int i = m; i < len; i++) {//先遍历后面的
sb.append(str.charAt(i));
}
for(int i = 0; i < m; i++) {//再遍历前面的
sb.append(str.charAt(i));
}
return sb.toString();
}
//工具方法
public void Reverse(char[] c, int p1, int p2) {
char temp;
temp = c[p1];
c[p1] = c[p2];
c[p2] = temp;
}
public void ReverseString(char[] c, int p1, int p2) {
while(p1 < p2){
Reverse(c, p1++, p2--);
}
}
}