算法训练营第八天|● 344.反转字符串 ● 541. 反转字符串II ● 剑指Offer 05.替换空格 ● 151.翻转字符串里的单词 ● 剑指Offer58-II.左旋转字符串

344 反转字符串

看完题后思路

把字符数组使用双指针反转.

思路

见上文

代码

            public void reverseString(char[] s) {
                int left=0,right=s.length-1;
                while (left<right){
                    char temp=s[left];
                    s[left]=s[right];
                    s[right]=temp;
                    left++;
                    right--;
                }
               
        }

复杂度分析

时间复杂度: 0(n)
空间复杂度 :0(1)
在这里插入图片描述

困难/进一步优化/收获

三刷直接过

541 反转字符串II

看完题后的思路

本题提高代码简洁性的一个关键是 for (int i = 0; i < chars.length; i+=2*k) {},当遇到数组中的元素是按定长的段处理时,都可以使用此方法

思路

见上文

代码

  public String reverseStr(String s, int k) {
            char[] chars = s.toCharArray();
            for (int i = 0; i < chars.length; i+=2*k) {
                int left=i,right=Math.min(i+k-1,chars.length-1);
                while (left<right){
                    char temp=chars[left];
                    chars[left]=chars[right];
                    chars[right]=temp;
                    left++;
                    right--;
                }
            }
            return String.valueOf(chars);
        }

复杂度

时间复杂度 0(n^2/k)
空间复杂度 0(n)

困难/进一步优化/收获

三刷直接过

剑指Offer 05.替换空格

看完题后的思路

额外开辟0(n)的空间,扫描源字符串,进行空格的替换.

思路

如何做到空间复杂度0(1),使用双指针法.可以先统计字符串中空格的数量,然后扩充字符串.

代码

 public String replaceSpace(String s) {
            StringBuilder sb = new StringBuilder();
            int preLength = s.length();
            for (int i = 0; i < s.length(); i++) {
                char c = s.charAt(i);
                if (c==' '){
                    sb.append("  ");
                }
            }
            s+=sb.toString();
            char[] chars = s.toCharArray();
            int end=chars.length-1,curr=preLength-1;
            
            while (curr>=0){
                if (chars[curr]==' '){
                    chars[end--]='0';
                    chars[end--]='2';
                    chars[end--]='%';
                    curr--;
                }else {
                    chars[end--]=chars[curr--];
                }
            }
            return String.valueOf(chars);
        }

复杂度

时间复杂度: 0(n)
空间复杂度 0(1)
在这里插入图片描述

困难/进一步优化/收获

三刷直接过

151. 反转字符串中的单词

看完题后的思路

本题的难点在于存在前导字符串 ,后置字符串,还有中间相隔好多字符串.
字符串的整体结构如下
在这里插入图片描述
将上面的红框作为一个处理单元,初始start=0,使用start探测第一个不为空格的字符.然后使用end探测至该单词的末尾.

思路

处理完空格问题,另一个问题是如何反转,不看代码随想录我能想到的就是使用一个栈接收每个单词,然后使用StringBuilder组装.

代码

 public String reverseWords(String s) {
        if (s==null||s.length()==0){
            return s;
        }
            int start=0; // 指向一个字符串的开头
            //ArrayDeque<String> stack = new ArrayDeque<>();
            Stack<String> stack = new Stack<>();
            while (start<s.length()){
                if (s.charAt(start)==' '){
                    start++;
                    continue;
                }
                // 此时start一定指向非空格字符
                int end=start+1;
                while (end<s.length()&&s.charAt(end)!=' '){
                    end++;
                }
                //此时end一定指向空格或末尾
                String substring = s.substring(start, end);
                stack.push(substring);
                start=end;
            }
            StringBuilder sb = new StringBuilder();
            while (!stack.isEmpty()){
                sb.append(stack.pop());
                sb.append(" ");
            }
            sb.delete(sb.length()-1,sb.length());
            return sb.toString();
        }

复杂度

时间复杂度 0(n)
空间复杂度 0(n)
在这里插入图片描述

如何降低空间复杂度?

困难/进一步优化/收获

进一步优化

删除多余空格—>反转字符串–>翻转字符串中的单词
难点: 删除多余的空格
可以使用双指针,但在字符串中如何使用双指针?
转换成字符数组—>处理–>System.arraycopy(chars, 0, newChars, 0, slow);

未完
三刷再刷一遍

剑指Offer58-II.左旋转字符串

思路

在这里插入图片描述

复杂度

时间复杂度 0(n)
空间复杂度 0(1)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弈师亦友

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值