【算法第六天7.19】反转字符串,反转字符串||,剑指 Offer 05. 替换空格,反转字符串的单词, 左旋转字符串

链接力扣344-反转字符串

链接力扣541-反转字符串||

链接剑指 Offer 05. 替换空格

链接力扣151- 反转字符串的单词

链接剑指 Offer 58 - II. 左旋转字符串

================================================

链接力扣344-反转字符串

思路:以中间为分界线,左右两个边界交换字符,依次向里收缩

java 复制代码
class Solution {
    public void reverseString(char[] s) {
        int n = s.length;
        for(int i = 0, j = n-1; i<j; i++,j--){
            char tmp = s[i];
            s[i] = s[j];
            s[j] = tmp;
        }
    }
}

链接力扣541-反转字符串||

思路

首先:字符串转化为字符数组

char[] res = s.toCharArray();

最后:将数组再转回字符串

return new String(res);

1、循环以2k为单位,

2、在这个2k长的数组中进行反转,需要有首尾索引

3、start就是i,end在循环过程中为i+k-1,如果到数组最后且不够k个,直接将length-1作为尾

java 复制代码
class Solution {
    public String reverseStr(String s, int k) {
        // 字符串转化为字符数组
        char[] res = s.toCharArray();
        // 这段的逻辑:
        // 1、循环以2k为单位,
        // 2、在这个2k长的数组中进行反转,需要有首尾索引
        // 3、start就是i,end在循环过程中为i+k-1,如果到数组最后且不够k个,直接将length-1作为尾
        for(int i = 0; i < res.length; i += 2*k){
            int start = i;
            int end = Math.min(start + k - 1, res.length-1);
            reverse(res,start,end);
        }
        return new String(res);
    }
    public char[] reverse(char[] ch,int i,int j){
        int n = ch.length;
        while(i < j){
            char tmp = ch[i];
            ch[i] = ch[j];
            ch[j] = tmp;
            i++;
            j--;
        }
        return ch;
    }
}

链接剑指 Offer 05. 替换空格

思路

循环过程中,都把字符串转为了字符数组,这样方便遍历

使用双指针方法,不使用额外空间

1、用StringBuider先把需要增加的空间给算出来

2、用两个指针:left指向旧字符串的末尾,right指向新字符串的末尾

一旦遇到旧字符的空位,新字符串需要加'0','2','%'这三个字符;

如果没遇到空位,则直接让新串right=旧串left;

最后再进行left--;right--

3、特殊情况:s串为空或者长度为0;遍历之后,发现s串中没有空格(需要添加的)

java 复制代码
class Solution {
    public String replaceSpace(String s) {
        // 如果s为空或者长度为0
        if(s == null || s.length() == 0) return s;
        char[] arr = s.toCharArray();
        StringBuilder str = new StringBuilder();
        for(int i = 0; i < arr.length; i++){
            if(arr[i] == ' '){
                str.append("  ");
            }
        }
        // 如果str为0,则说明原字符串无空格
        if(str.length() == 0) return s;
        int left = s.length()-1;
        //串的拼接
        s += str.toString();
        int right = s.length()-1;
        char[] ch = s.toCharArray();
        //循环条件:旧串一直到最前面一个
        while(left >= 0){
            if(ch[left] ==' '){
                ch[right--] = '0';
                ch[right--] = '2';
                ch[right] = '%';
            }else{
                ch[right] = ch[left];
            }
            left--;
            right--;
        }
        //最后,将字符数组直接放入String中
        return new String(ch);
    }
}

链接力扣151- 反转字符串的单词

思路

1、先处理单词中可能的多余空格

2、整个串全部反转

3、串中的单词逐个反转回来

java 复制代码
class Solution {
    public String reverseWords(String s) {
        StringBuilder sb = removeSpace(s);
        reverseString(sb,0,sb.length()-1);
        reEachWord(sb);
        return sb.toString();
    }

    private 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的第一个条件,保证空格前的单词可以进入sb中,
            // 当c == ' '时,第二个条件发挥作用
            // if的第二个条件,保证单词与单词间只有一个空格
            // 当c == ' '且sb.charAt(sb.length() - 1) == ' '时,则说明有多余的空格,start需要++
            if(c != ' ' || sb.charAt(sb.length() - 1) != ' '){
                sb.append(c);
            }
            start++;
        }
        return sb;
    }

/**
     * 反转字符串指定区间[start, end]的字符
     */
    public void reverseString(StringBuilder sb, int start, int end) {
        // System.out.println("ReverseWords.reverseString() called with: sb = [" + sb + "], start = [" + start + "], end = [" + end + "]");
        while (start < end) {
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
        }
        // System.out.println("ReverseWords.reverseString returned: sb = [" + sb + "]");
    }

    private void reEachWord(StringBuilder sb){
        int start = 0;
        int end = 1;
        int n = sb.length();
        // 第一个遍历:整个带空格的字符串的遍历
        while(start < n){
            // 第二个遍历:对每个单词进行遍历
            // 直到遍历到end为空结束
            while(end < n && sb.charAt(end) != ' '){
                end++;
            }
            // end - 1 是因为end现在指向的是空
            reverseString(sb,start,end-1);
            // end为空,+1是下一个单词的开始
            start = end + 1;
            end = start + 1;
        }
    }
}

链接剑指 Offer 58 - II. 左旋转字符串

思路

用substring的思路 :将前n个存到sb串中,把前几个截走,再接上sb串
不用substring的思路:先反转前n个,再反转后面的,最后整体反转一次

使用substring()

java 复制代码
class Solution {
    public String reverseLeftWords(String s, int n) {
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < n; i++){
            sb.append(s.charAt(i));
        }
        String newstr = s.substring(n);
        newstr += sb.toString();
        return newstr;
    }
}

三次反转代码

java 复制代码
class Solution {
    public String reverseLeftWords(String s, int n) {
        int len=s.length();
        StringBuilder sb=new StringBuilder(s);
        reverseString(sb,0,n-1);
        reverseString(sb,n,len-1);
        return sb.reverse().toString();
    }
     public void reverseString(StringBuilder sb, int start, int end) {
        while (start < end) {
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
            }
        }
}
相关推荐
alphaTao10 分钟前
LeetCode 每日一题 2025/3/31-2025/4/6
算法·leetcode
快来卷java14 分钟前
JVM虚拟机篇(五):深入理解Java类加载器与类加载机制
java·jvm·mysql
Andrew_Ryan15 分钟前
android use adb instsll cacerts
算法·架构
从零开始学习人工智能1 小时前
Docker 镜像导出与导入:export/import vs save/load
运维·docker·容器
Wx120不知道取啥名1 小时前
C语言跳表(Skip List)算法:数据世界的“时光穿梭机”
c语言·数据结构·算法·list·跳表算法
禾小西2 小时前
Java 逐梦力扣之旅_[204. 计数质数]
java·算法·leetcode
LuckyLay2 小时前
LeetCode算法题(Go语言实现)_32
算法·leetcode·golang
ゞ 正在缓冲99%…2 小时前
leetcode295.数据流的中位数
java·数据结构·算法·leetcode·
文弱_书生2 小时前
关于点扩散函数小记
数码相机·算法·数学原理
爪娃侠2 小时前
LeetCode热题100记录-【二叉树】
linux·算法·leetcode