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

LeetCode 344.反转字符串

简单题,注意循环的结束条件,踩坑:当数组的长度为偶数时,需要特殊处理一下s[s.length/2 -1]和s[s.length/2]。代码如下:

class Solution {
    public void reverseString(char[] s) {
        int k = 0;
        for(int i=s.length-1; i>s.length/2; i--){
            char temp = s[i];
            s[i] = s[k];
            s[k] = temp;
            k++;
        }
        if(s.length % 2 == 0){
            char temp = s[s.length/2];
            s[s.length/2] = s[s.length/2 - 1];
            s[s.length/2 - 1] = temp;
        }
    }
}

LeetCode 541. 反转字符串II

想法:本题与上题解法相似,每隔2k个反转前k个,最后如果数组长度整除k为偶数且有剩余字符,则全部反转,代码如下:

class Solution {
    public void reverse(char[] s, int start, int kn){
        int k=start;
        for(int i=start + kn-1; i> start + kn / 2; i--){
            char temp = s[i];
            s[i] = s[k];
            s[k] = temp;
            k++;
        }
        if(kn % 2 == 0){
            char temp = s[start + kn / 2];
            s[start + kn / 2] = s[start + kn / 2 - 1];
            s[start + kn / 2 - 1] = temp;
        }
    }
    public String reverseStr(String s, int k) {
        int count = s.length() / k;
        char[] ss = s.toCharArray();
        for(int i=0; i<count; i++){
            if(i %2 == 0){
                // 反转字符
                reverse(ss, i*k, k);
            }
        }
        if(count % 2 == 0 && s.length() > count * k){
            // 若模2k==0,且有剩余字符,则剩余字符全部反转
            reverse(ss, count*k, s.length()-count*k);
        }
        return new String(ss);
    }
}

剑指Offer 05.替换空格

刚开始用split方法过滤掉空格,但是发现处理不了"   "这种全是空格或者字符之间有多个空格的情况,最后只好转换为字符数组,逐个遍历,代码如下:

class Solution {
    public String replaceSpace(String s) {
        char[] ss = s.toCharArray();
        String result = new String();
        for(int i=0; i<ss.length; i++){
            if(ss[i] == ' '){
                result = result + "%20";
            }else{
                result = result + ss[i];
            }
        }
        return result;
    }
}

151.翻转字符串里的单词

首先去掉字符串首尾的空格,然后用split函数根据空格进行划分,类似于反转字符串一样的方法来反转单词顺序。踩坑:最后拼接字符串时,如果为空要continue,不然字符串内会有多余空格。代码如下:

class Solution {
    public String reverseWords(String s) {
        String[] ss = s.trim().split(" ");
        String result = new String();
        int k = 0;
        for(int i=ss.length-1; i> ss.length/2; i--){
            String temp = ss[i];
            ss[i] = ss[k];
            ss[k] = temp;
            k++;
        }
        if(ss.length % 2 == 0){
            String temp = ss[ss.length/2];
            ss[ss.length/2] = ss[ss.length/2 -1];
            ss[ss.length/2 - 1] = temp;
        }
        for(int i=0; i<ss.length; i++){
            if(ss[i] == "") continue;
            String item = ss[i].trim();
            if(i == 0){
                result = item;
            }else {
                result = result + " " + item;
            }
        }
        return result;
    }
}

这个题的难度是中等,但如果按我的思路来写就太简单了,抱着这一丝丝的犹豫点开了卡尔的文章,哈哈哈哈果不其然是我想简单了。于是乎按照文章的想法,重新写了一遍题。代码如下:

class Solution {
    public void reverse(char[] s, int start, int end){
        // 反转从start到end位置的字符(左闭右开)
        for(int i=end-1, j = start; i>j; i--, j++){
            char temp = s[i];
            s[i] = s[j];
            s[j] = temp;
        }
    }
    public String reverseWords(String s) {
        char[] ss = s.toCharArray();
        // 1.去除多余的空格
        int slow = 0;
        int k = 0;
        for(int i=0; i<ss.length; i++){
            if(ss[i] != ' '){
                if(slow != 0) ss[slow++] = ' ';
                while(i < ss.length && ss[i] != ' '){
                    ss[slow++] = ss[i++];
                }
            }
        }
        // 2.反转整个字符串
        reverse(ss, 0, slow);
        // 3.反转单词
        int start = 0;
        int end = 0;
        while(end < slow){
            if(ss[end] != ' '){
                end++;
            }else{
                reverse(ss, start, end);
                end++;
                start = end;
            }
        }
        reverse(ss, start, end);  // 翻转最后一个单词
        return new String(ss, 0, slow);
    }
}

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

简单水题解法:因为对java的操作并不熟悉,本着以在笔试时应最快方法解决问题,所以水题解法也会做一遍,主要是为了熟悉操作。代码如下:

class Solution {
    public String reverseLeftWords(String s, int n) {
        return s.substring(n, s.length()) + s.substring(0, n);
    }
}

翻转解法:1.先反转前n个字符;2.接着反转n到末尾字符;3.最后反转整个字符串,便可以得到最后的结果。代码如下:

class Solution {
    public void reverse(char[] s, int start, int end){
        for(int i=start, j=end-1; i<j; i++, j--){
            char temp = s[i];
            s[i] = s[j];
            s[j] = temp;
        }
    }
    public String reverseLeftWords(String s, int n) {
        char[] ss = s.toCharArray();
        reverse(ss, 0, n);
        reverse(ss, n, ss.length);
        reverse(ss, 0, ss.length);
        return new String(ss, 0, ss.length);
    }
}

总结

后两道简单题用O(1)空间复杂度来写,对字符串的反转操作更熟悉了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值