leetcode151.翻转字符串的单词

针对LeetCode151题《翻转字符串中的单词》,文章指出原解法中频繁创建新String对象的问题,并提出使用StringBuilder优化,以减少空间消耗。
摘要由CSDN通过智能技术生成

https://leetcode-cn.com/problems/reverse-words-in-a-string/

class Solution {
    public String reverseWords(String s) {
        char[] arr = s.toCharArray();
        reverse(arr, 0, arr.length - 1);
        StringBuffer res = new StringBuffer();
        int l = 0, r = arr.length - 1;
        //先把两端的空格收缩掉,记录l和r
        while(l < r){
            if(arr[l] == ' ') l++;
            if(arr[r] == ' ') r--;
            if(arr[l] != ' ' && arr[r] != ' ') break;
        }
        int flag = l, L = l,R;
        //对每个单词进行翻转,并且加入到res里去,单词之间只加一个空格,多余空格用while循环过滤掉
        while(flag < r) {
            if(arr[flag] == ' ') {
                R = flag - 1;
                reverse(arr,L,R);
                res.append(new String(arr).substring(L,R + 1));
                res.append(' ');
                while(arr[flag] == ' ') flag++;
                L = flag;
            }else {
                flag++;
            }
        }
        //上面的循环漏了最后一个单词,再补上
        reverse(arr,L,r);
        res.append(new String(arr).substring(L,r + 1));
        return res.toString();
        
    }
    public void reverse(char[] a, int l, int r) {
        char temp;
        while(l < r){
            temp = a[l];
            a[l] = a[r];
            a[r] = temp;
            l++;
            r--;
        }
    }
}

这个方法的劣势在于,每次都要new String整个arr数组,再取substring,因为arr数组每翻转一个单词都在变化,考虑换成stringbuilder进行操作,不用一直创建String空间。

class Solution {
    public String reverseWords(String s) {
        StringBuilder arr = makearr(s);
        reverse(arr, 0, arr.length() - 1);
        reverseEachword(arr);
        return arr.toString();
        
    }
    public void reverseEachword(StringBuilder s) {
        int n = s.length();
        int start = 0, end = 0;
        //遍历所有单词
        while(start < n) {
            //找到单词末尾,这里注意 end < n而不是end < n - 1,因为end可以取到n - 1 
            while(end < n && s.charAt(end) != ' ') end++;
            reverse(s, start, end - 1);
            //翻转后寻找下一个单词
            start = end + 1;
            end++;
        }
    }
    public StringBuilder makearr(String s){
        int l = 0, r = s.length() - 1;
        StringBuilder ans = new StringBuilder();
        char[] arr = s.toCharArray();
        int flag = 0;
        //先把两端的空格收缩掉,记录l和r
        while(l < r){
            if(arr[l] == ' ') l++;
            if(arr[r] == ' ') r--;
            if(arr[l] != ' ' && arr[r] != ' ') break;
        }
        //过滤中间的多余空格
        for(int i = l;i <= r;) {
            if(arr[i] != ' ') {
                ans.append(arr[i++]);
            }else {
                ans.append(arr[i]);
                while(arr[i] == ' ') i++;
            }
        }
        return ans;
    }
    public void reverse(StringBuilder a, int left, int right) {
        char temp;
        int l = left, r = right;
        while(l < r){
            temp = a.charAt(l);
            a.setCharAt(l++, a.charAt(r));
            a.setCharAt(r--, temp);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值