• LeetCode-151-中等-翻转字符串里面的单词


    问题描述

    给定一个字符串,逐个翻转字符串中的每个单词。

    说明:
    无空格字符构成一个 单词 。
    输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
    如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个

    示例 1:
    输入:“the sky is blue”
    输出:“blue is sky the”
    示例 2:
    输入:" hello world! "
    输出:“world! hello”
    解释:输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
    示例 3:
    输入:“a good example”
    输出:“example good a”
    解释:如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
    示例 4:
    输入:s = " Bob Loves Alice "
    输出:“Alice Loves Bob”
    示例 5:
    输入:s = “Alice does not even like bob”
    输出:“bob like even not does Alice”

    提示:

    1 <= s.length <= 104
    s 包含英文大小写字母、数字和空格 ’ ’
    s 中 至少存在一个 单词

    分析思路

    注意提示中加粗的部分,参数s前后可能有空格,要去掉前后的空格,单词与单词之间可能有多个空格,要减少到一个空格,所以判断当前字符数组中当前元素是不是空格,并且当前元素的前一个元素是不是空格,如果是连续的空格,只保留第一个空格,剩下的让不是空格的元素填充。最终得到一个合适的字符数组,计算出数组的有效长度。

    接下来就是翻转单词的操作了,我们先把整个数组翻转一次,然后再将每个单词翻转一次,这样单词就成了我们想要的样子。翻转的方法就是两个指针,一个从左开始,一个从右开始,两者指向的元素进行交换,当两个指针碰头的时候交换结束。左右指针分别就是这个单词的下标区间的左区间和右区间。

    单词翻转过后,还没有结束,因为我们规定单词语单词之间以空格分隔,但是最后一个单词的后面没有空格,需要对他进行额外的一次翻转,区间是[最后一个空格所在的下标+1,len);最终返回字符串,构造方法中传入的参数是字符数组,从0开始到len结束。

    代码实现

    具体每一步骤的解释都在注释中。

    public String reverseWords(String s) {
            if (s == null||s.equals("")){
                return null;
            }
            //翻转字符串
            char[] charArray = s.toCharArray();
            //cur是慢指针,len代表有效长度(去掉两端的空格和连续的空格)
            int cur=0,len = 0;
            //space表示当前字符的前一个是不是空格,true是空格,false不是
            boolean space = true;
            //先求出有效长度并将字符数组中多余的空格去掉
            for (int i = 0; i < charArray.length; i++) {
                //如果当前字符不是空格
                if(charArray[i]!=' '){
                    //将cur慢指针所指向的元素设置成当前元素
                    charArray[cur++] = charArray[i];
                    space = false;
                }else if(space==false){
                    //如果当前是空格,并且当前元素的前一个元素不是空格,将cur指向的元素设置成空格
                    charArray[cur++] = charArray[i];
                    space=true;
                }
            }
            //最终判断如果最后一个元素是空格,有效长度等于cur-1;否则等于cur
            len = space?cur-1:cur;
            //翻转字符串
            reverseStr(charArray,0,len);
    
            //区间翻转字符串,preIndex=-1起哨兵的作用
            int prevIndex = -1;
            for (int i = 0; i < len; i++) {
                //如果当前元素不是空格直接continue
                if(charArray[i]!=' '){
                   continue;
                }
                //是空格就进行区间翻转也是将一个个单词翻转
                reverseStr(charArray,prevIndex+1,i);
                //每次修改区间开始的位置就是空格所在的下标  [preIndex,i)
                prevIndex = i;
            }
            //翻转最后一个单词
            reverseStr(charArray,prevIndex+1,len);
            return new String(charArray,0,len);
        }
        //翻转指定区间内的字符数组
        private void reverseStr(char[] array,int li,int ri){
            ri--;
            while(li<ri){
                swap(array,li,ri);
                li++;
                ri--;
            }
        }
    	//交换两个元素
        private void swap(char [] array,int i,int j){
            char temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }
    

    在这里插入图片描述

    写有用的文章,希望对大家有所帮助!

  • 相关阅读:
    记录Spark 笛卡尔积问题
    接口和继承的区别
    SpringMVC使用可以访问静态资源,但是导致Controller访问失败
    Redis获取缓存异常:java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to XXX
    Spring MVC RedirectAttributes取值方法
    Resource interpreted as Stylesheet but transferred with MIME || DevTools failed to parse SourceMap:
    web.xml中filter加载顺序出现的问题
    kafka 与 rocketmq
    从小到大的部署架构
    SSH框架的简单实现
  • 原文地址:https://www.cnblogs.com/dataoblogs/p/14121826.html
Copyright © 2020-2023  润新知