《剑指offer》 -day3-字符串(简单)

剑指 Offer 05. 替换空格

题目描述

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

限制:

  • 0 < = s 的 长 度 < = 10000 0 <= s 的长度 <= 10000 0<=s<=10000
    剑指 Offer 05. 替换空格

解法一:StringBuilder

思路:

  • 使用 StringBuilder sb 来存放 新结果;
  • 若 s[i] 为空格,则将 “%20” 插入到 sb 中;
  • 否则,则将 s[i] 插入 sb 中
class Solution {
    public String replaceSpace(String s) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ' ') {
                sb.append("%20");
            } else {
                sb.append(s.charAt(i));
            }
        }
        return sb.toString();
    }
}
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

解法2:双指针

该方法在 C++ 语言中能使得空间复杂度将为 O ( 1 ) O(1) O(1),但是由于 Java 中 String 是不可变的,所以在 Java 中该方法空间复杂度仍为 O ( n ) O(n) O(n). (可以借鉴 双指针 思路)

思路:

  1. 统计 s 中 空格 个数 s p a c e s spaces spaces
  2. 创建用于存放 新s 的数组 char[] arr = new char[n + 2 * spaces];
  3. 双指针 从后向前 遍历:
    • 若 s[i] 为空格,则将 arr[j] 向前分别添加 ‘0’、‘2’、’%’ (注意 逆序 );
    • 否则,直接将 s[i] 赋给 arr[j]
class Solution {
    public String replaceSpace(String s) {
        int n = s.length();
        int spaces = 0; // 空格个数
        for (int i = 0; i < n; i++) {
            if (s.charAt(i) == ' ') spaces++;
        }
        char[] arr = new char[n + 2 * spaces]; // 新的s
        int newLen = arr.length;
        int i = n - 1; // s
        int j = newLen - 1; // 新 s
        while (i >= 0) {
            if (s.charAt(i) == ' ') {
                // 替换空格为 “%20”,但要注意此时是 逆序
                arr[j--] = '0';
                arr[j--] = '2';
                arr[j--] = '%';
            } else {
                arr[j--] = s.charAt(i);
            }
            i--;
        }
        return new String(arr);
    }
}
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n) (Java 中 String 不可变,在 C++ 中可以降为 O ( 1 ) O(1) O(1)

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

题目描述

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

限制:

  • 1 < = k < s . l e n g t h < = 10000 1 <= k < s.length <= 10000 1<=k<s.length<=10000

解法一:StringBuilder

思路:

  • 使用 StringBuilder 保存新的 s
  • 截取 s[n, len) 到 sb;
  • 截取 s[0, n) 到 sb
class Solution {
    public String reverseLeftWords(String s, int n) {
        StringBuilder sb = new StringBuilder();
        // s[n, len)
        for (int i = n; i < s.length(); i++) sb.append(s.charAt(i));
        // s[0, n)
        for (int i = 0; i < n; i++) sb.append(s.charAt(i));
        return sb.toString();
    }
}
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

双指针:局部反转 + 整体反转

思路:

  1. 局部反转:s[0, n - 1];
  2. 局部反转:s[n - 1, len - 1];
  3. 整体反转:s[0, len - 1].
class Solution {
    public String reverseLeftWords(String s, int n) {
        int len = s.length();
        char[] arr = s.toCharArray();
        // 局部反转
        reverse(arr, 0, n - 1);
        // System.out.println(Arrays.toString(arr));
        reverse(arr, n, len - 1);
        // 整体反转
        reverse(arr, 0, len - 1);
        return new String(arr);
    }

    // 反转 s[left, right] 中字符
    public void reverse(char[] arr, int left, int right) {
        // 双指针
        while (left < right) {
            char temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
}
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n) (如果使用 C++、或者题目给的是 char[],则可以将 空间复杂度降为 O ( 1 ) O(1) O(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值