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);
        
    }

}
View Code

解法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);
    }

}
View Code

举一反三:

单词翻转:输入一个英文句子,反转句子中单词的顺序。要求单词内字符的顺序不变,句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。例如,若输入"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);
        
    }

}
View Code

 

posted @ 2016-05-16 17:20  爱学习的小瓜牛  阅读(286)  评论(0编辑  收藏  举报