如把字符串abcdef左旋转2位得到字符串cdefab。
请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1)。
以下算法实现了可以做旋转和右旋转....
原理:
abcde123456
根据要旋转的位数k,把数组分成两子串,例如K=6,进行右旋转,则把字符串分成 abcde 和 123456(K位)
划分技巧:右旋转,后面子串位数为K,剩下做为前面子串;若是左旋转,前面子串位数为K,剩下做为后面子串
如果上面 abcde123456 进行左旋转 K=6位,则字符串的划分是:abcde1(K位) 和 23456
接着对abcde和123456分别进行逆序操作结果:
edcba和654321
合并后成
edcba654321
再整体逆序
123456abcde
优点: 3个reverse 操作都是线性操作,前两个时间复杂度和为0(n/2),最后一个整体逆序时间复杂度为0(n/2),总时间复杂度是O(n),比起普通的相同功能算法时间复杂度要低
import java.util.Scanner;
public class ChangeString {
public static void main(String args[]){
System.out.println("请输入字符串:");
Scanner input=new Scanner(System.in);
char[] charArray=input.nextLine().toCharArray();
System.out.println("输入要移动的位数");
//int shiftNum=Integer.parseInt(input.nextLine());
int innum=input.nextInt();
System.out.print("字符串为:"+new String(charArray)+"移动位数为:"+innum);
charArray=Left(innum,charArray);
System.out.print("结果为:"+String.valueOf(charArray));
}
private static char[] reverse(char[] src,int begin,int end){
char temp;
for(;begin<end;end--,begin++){
temp=src[begin];
src[begin]=src[end];
src[end]=temp;
}
return src;
}
private static char[] Left(int k,char[] src){
src=reverse(src,0,k-1);
src=reverse(src,k,src.length-1);
src=reverse(src,0,src.length-1);
return src;
}
private static char[] Right(int k,char[] src){
src=reverse(src,0,src.length-k-1);
src=reverse(src,src.length-k,src.length-1);
src=reverse(src,0,src.length-1);
return src;
}
}