代码随想录Day8

题目列表

  • 344.反转字符串(LeetCode)
  • 541.反转字符串II(LeetCode)
  • 卡码网:54.替换数字

解题过程

344.反转字符串

题目描述

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

解题思路

因为要求原地修改,数组又是连续存放的,可以想到直接让对应位置的数字进行交换,也就是匆匆头尾开始交换一直到中间。

代码展示

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

541.反转字符串II

题目描述

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例 1:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
示例 2:
输入:s = "abcd", k = 2
输出:"bacd"
提示:
1 <= s.length <= 104
s 仅由小写英文组成
1 <= k <= 104

解题思路

这相当于自定义一种反转规则。
这道题有一个前提条件:每次要计数2k个;
反转主要有两种规则:看从本次计数起始的位置看是否够 k 个,如果有则反转这k个数,如果不够,则直接反转剩下的数。

注意事项

判断条件

if(i + k <= ch.length),这里的判断条件意味着剩余字符大于或等于 k 个,在这种情况下,就可以反转前 k 个。

代码展示

class Solution {
    public String reverseStr(String s, int k) {
        char[] ch = s.toCharArray();
        for(int i = 0; i < ch.length; i += k*2){

            if(i + k <= ch.length){
                reverse(ch, i, i + k - 1);
            }else{
                reverse(ch, i, ch.length - 1);
            }
        }
        return new String(ch);
    }
    public void reverse(char[] ch, int l, int r){
        for(; l < r; l++,r--){
            char temp = ch[l];
            ch[l] = ch[r];
            ch[r] = temp;
        }
    }
}

卡码网:54.替换数字

题目描述

题目描述
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。
输入描述
输入一个字符串 s,s 仅包含小写字母和数字字符。
输出描述
打印一个新的字符串,其中每个数字字符都被替换为了number
输入示例
a1b2c3
输出示例
anumberbnumbercnumber
提示信息
数据范围:
1 <= s.length < 10000。

解题思路

第一想法是使用可变字符串的 append() 方法。
但看题解这道题意在练习双指针的使用。
双指针解法:

  • 首先要根据原字符串中的数字的个数算出新字符串的长度,“number”比 0 - 9 多了五个字符。
  • 然后根据新的长度先 new 一个字符数组,然后把原字符串先放到字符数组里。
  • 接下来在字符数组上使用双指针,一个指针 old 指向原字符串对应的末尾字符,一个指针 new 指向字符数组的最后一位,准备从最后一位开始填充新数组。
  • 如果 old 指向是字母,那就把字母填到 old 指的位置;如果 old 指向是数字,那 new 指向位置就把“number” 倒着填进去,边填充边移动。
  • 填充完之后 new 移动到下一个位置,等待 old 向前一位进行新的判断,直到 old 移动到 0 。

注意事项

String 是不可变字符串

代码展示

//双指针写法
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.next();
        int originalLength = s.length();

        int count = 0;
        for (int i = 0; i < originalLength; i++) {
            if (Character.isDigit(s.charAt(i))) {
                count++;
            }
        }

        int newLength = originalLength + count * 5; 
        char[] ch = new char[newLength];

        int newIndex = newLength - 1;
        for (int oldIndex = originalLength - 1; oldIndex >= 0; oldIndex--) {
            char c = s.charAt(oldIndex);
            if (Character.isDigit(c)) {
                ch[newIndex--] = 'r';
                ch[newIndex--] = 'e';
                ch[newIndex--] = 'b';
                ch[newIndex--] = 'm';
                ch[newIndex--] = 'u';
                ch[newIndex--] = 'n';
            } else {
                ch[newIndex--] = c;
            }
        }
        System.out.println(new String(ch));
    }
}
//直接使用StringBuilder
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.next();
        char[] ch = s.toCharArray();
        StringBuilder newS = new StringBuilder();
        for(char c : ch){
            if(Character.isDigit(c)){
                newS.append("number");
            }else{
                newS.append(c);
            }
        }
        System.out.println(newS);
    }
}

参考资料

代码随想录

posted @ 2025-04-30 21:03  cbdsszycfs  阅读(219)  评论(0)    收藏  举报