代码随想录算法训练营第八天|第四章 字符串part01 344.反转字符串 541. 反转字符串II 卡码网:54.替换数字

 344.反转字符串

题目链接:344. 反转字符串 - 力扣(LeetCode)

讲解链接:代码随想录

翻转字符 直接代码

Java代码:

class Solution {
    public void reverseString(char[] s) {
        //先写位运算
        int l = 0;
        int r = s.length - 1;
        while(l < r){
            s[l] ^= s[r];
            s[r] ^= s[l];
            s[l] ^= s[r];
            l++;
            r--;
        }
    }
}//直接用temp
class Solution {
    public void reverseString(char[] s) {
        int l = 0;
        int r = s.length - 1;
        while(l < r){
            char temp = s[l];
            s[l] = s[r];
            s[r] = temp;
            l++;
            r--;
        }
    }
}

简单 下一个

 541. 反转字符串II

题目链接:541. 反转字符串 II - 力扣(LeetCode)

讲解链接:代码随想录

 说实话题看不太懂 感觉有点绕。。

看看代码随想录 和上面的翻转就是加了个要求 对前k个字符进行翻转

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

看不太懂,, 再多想想

Java代码:

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;
            //判断尾数够不够k个来取决end指针的位置
            int end = Math.min(ch.length - 1, start + k - 1);
            /*
            输入:s = "abcdefg", k = 2
            输出:"bacdfeg"
            */
            while(start < end){

                char temp = ch[start];
                ch[start] = ch[end];
                ch[end] = temp;

                start++;
                end--;
            }
        }
        return new String(ch);
    }
}

卡码网:54.替换数字

题目链接:54. 替换数字(第八期模拟笔试)

讲解链接:替换数字 | 代码随想录

 给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。

输入描述

输入一个字符串 s,s 仅包含小写字母和数字字符。

输出描述

打印一个新的字符串,其中每个数字字符都被替换为了number

代码随想录实现:

如果想把这道题目做到极致,就不要只用额外的辅助空间了! (不过使用Java刷题的录友,一定要使用辅助空间,因为Java里的string不能修改)

首先扩充数组到每个数字字符替换成 "number" 之后的大小。

例如 字符串 "a5b" 的长度为3,那么 将 数字字符变成字符串 "number" 之后的字符串为 "anumberb" 长度为 8。

如图:(转自代码随想录)

然后从后向前替换数字字符 也就是双指针法 过程如下 i指向新长度的末尾 j指向旧长度的末尾

为什么要从后向前填充 从前向后填充不行么 

从前向后填充就是O(n^2)的算法了 因为每次添加元素都要将添加元素之后的所有元素整体向后移动

其实很多数组填充类的问题 其做法都是先预先给数组扩容带填充后的大小 然后在从后向前进行操作

这么做有两个好处:

  1. 不用申请新数组。
  2. 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。

Java代码:(需要注意的是 用java的string申请空间时是固定的 需要再申请新空间处理)

import java.util.Scanner;

public class Main{
    public static String replacenumber(String s){
        int count = 0;//统计数字的个数
        int sOldsize = s.length();
        for(int i = 0; i < s.length(); i++){
            if(Character.isDigit(s.charAt(i))){
                count++;
            }
        }
        //扩充字符串s的大小 也就是每个空格替换成‘number’之后的大小
        char[] news = new char[s.length() + count * 5];
        int sNewsize = news.length;
        //把旧字符串的内容填入news
        System.arraycopy(s.toCharArray(), 0, news, 0, sOldsize);
        //从后往前把空格替换为number
        for(int i = sNewsize - 1, j = sOldsize - 1; j < i;j--, i--){
            if(!Character.isDigit(news[j])){//遇到字母了
                news[i] = news[j];
            }else{//遇到数字了
                news[i] = 'r';
                news[i - 1] = 'e';
                news[i - 2] = 'b';
                news[i - 3] = 'm';
                news[i - 4] = 'u';
                news[i - 5] = 'n';
                i -= 5;
            }
        }
        return new String(news);
    };
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        String s = scanner.next();
        System.out.println(replacenumber(s));
        scanner.close();
    }
}

看看八股 去看计网去 今天也是不能浪费的一天

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值