代码随想录算法训练营第8天 | 344、541、剑指Offer 05、151、剑指Offer 58

344.反转字符串

题目描述

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例1:
输入: s = [ " h " , " e " , " l " , " l " , " o " ] s = ["h","e","l","l","o"] s=["h","e","l","l","o"]
输出: [ " o " , " l " , " l " , " e " , " h " ] ["o","l","l","e","h"] ["o","l","l","e","h"]
示例2:
输入: s = [ " H " , " a " , " n " , " n " , " a " , " h " ] s = ["H","a","n","n","a","h"] s=["H","a","n","n","a","h"]
输出: [ " h " , " a " , " n " , " n " , " a " , " H " ] ["h","a","n","n","a","H"] ["h","a","n","n","a","H"]

思路

简单地使用双指针交换即可。

解法1

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

解法2

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

总结

本题解法思想很简单,双指针的使用十分顺理成章。值得注意的是,拓展了位运算在反转字符串操作中的应用。

541.反转字符串Ⅱ

题目描述

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例1:
输入: s = " a b c d e f g " , k = 2 s = "abcdefg", k = 2 s="abcdefg",k=2
输出: " b a c d f e g " "bacdfeg" "bacdfeg"

思路

只需在反转字符串的基础上规定一个范围和循环时的步长即可

解法

class Solution {
    public String reverseStr(String s, int k) {
        char[] ch = s.toCharArray();
        for(int i=0;i<ch.length;i+=2*k){
            int start = i;
            int end = Math.min(ch.length-1,start+k-1);
            while(start < end){
                ch[start] ^= ch[end];
                ch[end] ^= ch[start];
                ch[start] ^= ch[end];
                start++;
                end--;
            }
        }
        return new String(ch);
    }
}

总结

本题需要注意能够想到用步长的规定来实现这种k个反转的效果。

剑指Offer 05.替换空格

题目描述

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例1:
输入:s = “We are happy.”
输出:“We%20are%20happy.”

思路

使用StringBuilder然后遍历即可

解法

class Solution {
    public String replaceSpace(String s) {
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<s.length();i++){
            char c = s.charAt(i);
            if(c == ' '){
                sb.append("%20");
            }
            else{
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

总结

简单题,常规做即可

151. 反转字符串中的单词

题目描述

给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例1:
输入: s = " t h e s k y i s b l u e " s = "the sky is blue" s="theskyisblue"
输出: " b l u e i s s k y t h e " "blue is sky the" "blueisskythe"
示例2:
输入: s = " h e l l o w o r l d " s = " hello world " s="helloworld"
输出: " w o r l d h e l l o " "world hello" "worldhello"
示例1:
输入: s = " a g o o d e x a m p l e " s = "a good example" s="agoodexample"
输出: " e x a m p l e g o o d a " "example good a" "examplegooda"

思路

本题最好可以将需要操作的步骤分布进行
首先,需要去除多余的空格
接下来,反转字符串
而反转字符串也有不同的思路,可以先全部反转后每个词反转,或者直接识别出每个词直接进行翻转。

解法1

class Solution {
    public String reverseWords(String s) {
        StringBuilder sb = removeSpace(s);
        reverseString(sb,0,sb.length()-1);
        reverseEachWord(sb);
        return sb.toString();
    }
    public StringBuilder removeSpace(String s){
        int start = 0;
        int end = s.length()-1;
        while(s.charAt(start) == ' ') start++;
        while(s.charAt(end) == ' ') end--;
        StringBuilder sb = new StringBuilder();
        while(start <= end){
            char c = s.charAt(start);
            if(c !=' ' || sb.charAt(sb.length()-1)!=' '){
                sb.append(c);
            }
            start++;
        }
        return sb;
    }
    public void reverseString(StringBuilder sb,int start,int end){
        while(start < end){
            char tmp = sb.charAt(start);
            sb.setCharAt(start,sb.charAt(end));
            sb.setCharAt(end,tmp);
            start++;
            end--;
        }
    }
    public void reverseEachWord(StringBuilder sb){
        int start = 0;
        int end = 1;
        int n = sb.length();
        while(start < n){
            while(end<n && sb.charAt(end)!=' '){
                end++;
            }
            reverseString(sb,start,end-1);
            start = end +1;
            end = start +1;
        }
    }
}

解法2

class Solution {
    public String reverseWords(String s) {
        char[] initialArr = s.toCharArray();
        char[] newArr = new char[initialArr.length+1];
        int newArrPos = 0;
        int i = initialArr.length-1;
        while(i>=0){
            while(i>=0 && initialArr[i] == ' '){
                i--;
            }
            int right = i;
            while(i>=0 && initialArr[i] !=' '){
                i--;
            }
            for(int j = i+1;j<=right;j++){
                newArr[newArrPos++] = initialArr[j];
                if(j == right){
                    newArr[newArrPos++] = ' ';
                }
            }
        }
        if(newArrPos == 0){
            return "";
        }
        else{
            return new String(newArr,0,newArrPos-1);
        }
    }
}

总结

本题注意分步进行,接下来就是每一步进行模拟。同时注意,在java中String是不可修改的,若需要修改则可考虑StringBuilder

剑指Offer 58-Ⅱ.左旋转字符串

题目描述

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
示例1:
输入: s = " a b c d e f g " , k = 2 s = "abcdefg", k = 2 s="abcdefg",k=2
输出: " c d e f g a b " "cdefgab" "cdefgab"
示例2:
输入: s = " l r l o s e u m g h " , k = 6 s = "lrloseumgh", k = 6 s="lrloseumgh",k=6
输出: " u m g h l r l o s e " "umghlrlose" "umghlrlose"

思路

一个简单的字符串拼接操作

解法

class Solution {
    public String reverseLeftWords(String s, int n) {
        StringBuilder sb = new StringBuilder();
        int i=0,j=n;
        while(j<s.length()){
            char ch = s.charAt(j);
            sb.append(ch);
            j++;
        }
        while(i<n){
            char ch = s.charAt(i);
            sb.append(ch);
            i++;
        }
        return sb.toString();
    }
}

总结

没啥可总结的,本题是简单的字符串拼接操作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值