剑指Offer对答如流系列

面试题58:翻转字符串

问题描述

问题(1) 翻转单词顺序

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。

例如输入字符串"I am a student. ",则输出"student. a am I"。

问题(2)左旋转字符串

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。

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

问题分析

问题(1)分析

最容易想到的思路是通过遍历字符串,遇到空格便截取一个单词。对Java Sring API熟悉的会用split()方法,不过这样效率低下,且占用空间较大。

仔细思考的话,我们其实可以在首尾两端各放置一个索引,交换索引位置的字符,两端索引往中间移动即可。之后根据空格的位置,对每个单词使用同样的方法进行翻转就行了。

问题(2)分析

思路和题翻转单词顺序的思路几乎一模一样。

以数字索引为分界,先分别翻转前半部分字符串和后半部分字符串,最后翻转整个字符串即可。

问题解答

问题(1)

 public String ReverseSentence(char[] chars) {
        if(chars==null || chars.length<=0) {
            return String.valueOf(chars);
        }
        //翻转整个句子
        reverseSb(chars,0,chars.length-1);
        //翻转单词(指针指向单词的第一个和最后一个)
        int start=0;
        int end=0;
        while(start<chars.length){
            while(end<chars.length && chars[end]!=' ') {
                end++;
            }
            reverseSb(chars,start,end-1);
            start=++end;
        }
        return String.valueOf(chars);
    }

    private void reverseSb(char[] chars,int start,int end){
        while(start < end){
            char temp=chars[start];
            chars[start]=chars[end];
            chars[end]=temp;
            start++;
            end--;
        }
    }

问题(2)

    public String leftRotateString(char[] chars,int n) {
        if(chars==null ||chars.length<=0) {
            return String.valueOf(chars);
        }
        if(n<=0 || n>chars.length) {
            return String.valueOf(chars);
        }
        reverse(chars,0,n-1);
        reverse(chars,n,chars.length-1);
        reverse(chars,0,chars.length-1);
        return String.valueOf(chars);
    }

    private void reverse(char[] chars, int start,int end){
        while(start<end){
            char temp=chars[start];
            chars[start]=chars[end];
            chars[end]=temp;
            start++;
            end--;
        }
    }
原文地址:https://www.cnblogs.com/JefferyChenXiao/p/12249447.html