(剑指Offer 58 - I.)Leetcode#151. 翻转字符串里的单词(Java解法+双指针解法)

41 篇文章 0 订阅
17 篇文章 0 订阅

问题描述:

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

说明:

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

示例 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 中 至少存在一个 单词

进阶:

    请尝试使用 O(1) 额外空间复杂度的原地解法。

来源:力扣(LeetCode)

解题思路:

这道题首先容易想到是使用split、trim、replace等方法去解。

但是不调用库函数的情况下的解法,主要分三步:

  1. 先反转整个数组:反转整个数组时就用到双指针直接在原数组上交换元素反转数组的解法。

  2. 清除多余空格:

    清除多余空格时,也是使用快慢指针。slow与fast指针初始值均为0.fast指针先移动找到第一个不为空格的位置(单词),

    再将单词移到字符串的最前方(以slow为下标)。再手动加一个空格作为间隔符。

    移动所有单词之后,slow所在的位置就是新字符串(不包括多余指针的字符串)长度。

  3. 再反转单个单词

    反转单个单词时,即从去掉空格的字符串中0下标开始,设置快慢双指针,slow指到单词开始下标处,fast指到单词结束下标处(空格前面的位置)。再调用反转全部的方法反转这个单词即可。

Java解法:

class Solution {
    public String reverseWords(String s) {
        char [] ss = s.toCharArray();
        int n = ss.length;
        reverse(ss,0,n-1);
        String newstr = black(ss,n);
        int nn = newstr.length();
        return wordreverse(newstr.toCharArray(),nn);
    }
    public void reverse(char[] ss,int i,int j){ //反转所有元素
        while(i<j){
            char tmp = ss[i];
            ss[i++] = ss[j];
            ss[j--] = tmp;
        }
    }
    public String black(char[] ss,int n){  //去除空格
        int fast = 0,slow = 0;
        while(fast<n){
            while(fast<n && ss[fast]==' ') fast++;
            while(fast<n && ss[fast]!=' ') ss[slow++]=ss[fast++];
            while(fast<n && ss[fast]==' ') fast++;
            if(fast<n) ss[slow++] = ' ';
        }
        return new String(ss).substring(0,slow);
    }
    public String wordreverse(char[] ss,int n){  //反转单个单词
        int slow=0,fast=0;
        while(fast<n){
            while( fast<n && ss[fast]!=' ') fast++;
            reverse(ss,slow,fast-1);
            slow = fast;
            while(slow<n && ss[slow]==' ') slow++;
            fast = slow;
            
        }
        return new String(ss);
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值