1.1字符串的旋转
题目:给定一个字符串,要求将字符串的前面若干个字符移到字符串的尾部。如有字符串“abcdef”,将前3个字符移到字符串尾部变成“defabc”。写一个函数实现此功能。
解法1:蛮力移位
比如将'a'移动到最后一位,就将'a'赋值给一个临时变量,然后把后面n-1个字符均向前移动一位(注意移动的时候由前向后依次进行,否则会将有用的值覆盖掉),最后将临时变量中的字符赋值给最后一位。若要移动m位字符,就重复调用这个函数m次;对于长度为n的字符串,,假设需要移动m个字符到尾部,总共需要m*n次移动,因此时间复杂度为O(mn),
空间复杂度为O(1)。
参考代码如下:
public class ReversrString1 { public static void ReverseString1(char[] sa,int len,int m) { if (len <= m){ System.out.println("sa is too small!!"); } char t = sa[0]; for(int i = 1;i<len;i++){ char temp = sa[i]; sa[i-1] = temp; } sa[len-1] = t; } public static void LeftRotateString(String str, int m) { if (str == null||str.length() == 0){ System.out.println("null"); } int n = str.length(); char[] sa = str.toCharArray(); while(m-->0){ ReverseString1(sa,n,m); } System.out.print(sa); } public static void main(String[] args) { // TODO Auto-generated method stub int m = 4; String str = "abcdef"; LeftRotateString(str,m); } }
解法2:三次反转
思路:先将一个字符串分割成两个部分,然后把这两个部分的字符串分别反转,最后再对整个字符串进行整体反转,即可解决问题。
举个栗子:输入:字符串"abcdef”,移动3位
输出:字符串"defabc”
1、将原字符串划分为两个部分,X = "abc",Y = "def"
2、反转X得到"cba",反转Y得到"fed"
3、最后将"cbafed"整体反转,得到"defabc"
这种把字符串先分为两个部分,各自反转,再整体反转的方法称为“三步反转”法,其时间复杂度为O(n),空间复杂度为O(1)
参考代码如下:
public class ReverseString2 { public static void ReverseString(char[] sa,int from,int to) { while(from<to){ char t = sa[from]; sa[from++] = sa[to]; sa[to--] = t; } } public static void LeftRotateString(String str,int m) { if(str == null || str.length() == 0){ System.out.print("It's wrong!"); } int n = str.length(); if (m>n){ m = m%n; } char[] sa = str.toCharArray(); ReverseString(sa,0,m-1); ReverseString(sa,m,n-1); ReverseString(sa,0,n-1); System.out.println(sa); } public static void main(String[] args) { // TODO Auto-generated method stub String str = "abcdef"; int m = 3; LeftRotateString(str,m); } }
举一反三:
单词翻转:输入一个英文句子,反转句子中单词的顺序。要求单词内字符的顺序不变,句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。例如,若输入"I am a student.",则输出"student. a am I"。
我依然采用三次反转的思路解决这题,主要是为了巩固前面学习的反转思路。网上还有很多大牛采用StringBuffer的方法也可方便解决问题。
思路:现将整体字符反转,再将每个单词反转
时间复杂度为O(n),空间复杂度为O(1)。
参考代码如下:
public class ReverseEnglishSentence { private static char[] a; public static String ReverseString(char[] sa,int from ,int to) { while(from<to){ char t = sa[from]; sa[from++] =sa[to]; sa[to--] = t; } return String.valueOf(sa); } public static void LeftRotateString(String str) { if(str == null||str.length() == 0){ System.out.println("It's wrong!"); } char[] sa = str.toCharArray(); int len = sa.length; char[] saAll = ReverseString(sa,0,len-1).toCharArray(); int j = 0; String a = null; for(int i = 0;i<len;i++){ if (saAll[i] == ' ' || i == len-1 ){ a = ReverseString(saAll,j,i-1); j =i+1; } } System.out.print(a); } public static void main(String[] args) { // TODO Auto-generated method stub String str = "I am a student."; LeftRotateString(str); } }