Bootstrap

代码随想录算法训练营Day8 | 344.反转字符串、541.反转字符串Ⅱ、替换数字

344.反转字符串

题目

344. 反转字符串 - 力扣(LeetCode)

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 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 码表中的可打印字符

思路

视频讲解:344.反转字符串

双指针秒了

题解

代码随想录:反转字符串

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

541.反转字符串Ⅱ

题目

541. 反转字符串 II - 力扣(LeetCode)

给定一个字符串 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

思路

视频讲解:541. 反转字符串II

代码随想录 :反转字符串Ⅱ

解题之前先将所给的字符串转换为字符数组。

自己解题时的主要错误点:for 循环每次递进1,写了一堆多余代码用于获取每 2k 个字符中的前 k 个字符。

当依照某种固定规律一段一段处理字符串时,可以思考能否在for循环的表达式上做文章。

注意点:

  • for循环每次递进2k个数
  • 返回时将字符数组转换回字符串
  • 可以使用库函数减少条件判断的重复代码

题解

独立题解:

能成功通过,但是复杂度过高,而且很难看懂(

class Solution {
    public String reverseStr(String s, int k) {
        char[] arr = s.toCharArray();
        int num = 0;
        for (int i = 1; i <= s.length(); i++) {
            if (i % (2 * k) == 0) {
                reverse(arr, i - 2 * k, i - 1 - k);
                num = i;
            }
            if (i == s.length() && i - num < k)
                reverse(arr, num, i - 1);
            else if (i == s.length() && i - num < 2 * k)
                reverse(arr, num, num - 1 + k);
        }
        return new String(arr);
    }

    void reverse(char[] s, int left, int right) {
        while (left < right) {
            char tmp = s[left];
            s[left] = s[right];
            s[right] = tmp;
            left++;
            right--;
        }
    }
}

看完视频后题解:

class Solution {
    public String reverseStr(String s, int k) {
        char[] arr = s.toCharArray();
        for (int i = 0; i < s.length(); i += 2 * k) {
            if (i + k - 1 >= s.length()) {
                reverse(arr, i, s.length() - 1);
                break;
            }
            reverse(arr, i, i + k - 1);
        }
        return new String(arr);
    }
    
    void reverse(char[] s, int left, int right) {
        while (left < right) {
            char tmp = s[left];
            s[left] = s[right];
            s[right] = tmp;
            left++;
            right--;
        }
    }
}

//再优化
class Solution {
    public String reverseStr(String s, int k) {
        char[] arr = s.toCharArray();
        for (int i = 0; i < s.length(); i += 2 * k) {
            //使用库函数减少判断代码
            reverse(arr, i, Math.min(i + k - 1, s.length() - 1));
        }
        return new String(arr);
    }

    void reverse(char[] s, int left, int right) {
        while (left < right) {
            char tmp = s[left];
            s[left] = s[right];
            s[right] = tmp;
            left++;
            right--;
        }
    }
}

替换数字

题目

54. 替换数字(第八期模拟笔试) (kamacoder.com)

本题使用ACM输入输出模式

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

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

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

输入示例:

a1b2c3

输出示例:

anumberbnumbercnumber

提示信息:

数据范围:
1 <= s.length < 10000

思路

代码随想录:替换数字

注意点:Java中的String不能修改,只能创建新的空间,或者使用StringBuilder来构建字符串。

  1. scanner.next()获取输入的字符串
  2. 将字符串转换为字符数组,遍历字符数组
  3. 判断字符是否为数字可以使用函数Character.isDigit()
  4. 使用StringBilder构建字符串,更方便拼接字符串
  5. 如果选择使用String,则先遍历一次字符数组以获取数字的个数,再相应地扩大数组大小,创建新数组,然后在新数组中进行填充

题解

使用StringBuilder

import java.util.Scanner;

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

使用String

import java.util.Scanner;
 
public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.next();
        int count = 0;
        char[] arr = s.toCharArray();
        for(char c : arr ) {
            if(Character.isDigit(c))
                count++;
        }
        int newlen = s.length()+ 5 * count;
        char[] res = new char[newlen];
        for(int i = 0, j = 0; j<newlen; i++,j++){
            if(!Character.isDigit(arr[i])){
                res[j] = arr[i];
            }else {
                res[j++] = 'n';
                res[j++] = 'u';
                res[j++] = 'm';
                res[j++] = 'b';
                res[j++] = 'e';
                res[j] = 'r';
            }
        }
        scanner.close();
        System.out.println(res);
    }
}
;