Skip to content

串编辑

单词反转

151. 反转字符串中的单词 mid

剑指 Offer 58 - I. 翻转单词顺序

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s 中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

反转整个 s, 然后反转每个单词即可

java
class Solution {
    public String reverseWords(String s) {
        return String.join(" ", Arrays.asList(s.trim().split("\\s+")).reversed());
    }
}
java
class Solution {
    public String reverseWords(String s) {
        String[] arr = s.split(" ");
        StringBuilder sb = new StringBuilder();
        for (int i = arr.length - 1; i >= 0; i--) {
            String ss = arr[i];
            if (!"".equals(ss)) sb.append(ss).append(" ");
        }
        return sb.toString().trim();
    }
}

344. 反转字符串 easy

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

java
class Solution {
    public void reverseString(char[] s) {
        int i = 0, j = s.length - 1;
        while (i < j) {
            swap(s, i++, j--);
        }
    }
}

345. 反转字符串中的元音字母 easy

给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。

元音字母包括 'a'、'e'、'i'、'o'、'u',且可能以大小写两种形式出现。

解法 双指针

java
class Solution {
    public String reverseVowels(String s) {
        char[] arr = s.toCharArray();
        Set<Character> set = Set.of('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U');
        for (int i = 0, j = s.length() - 1; ; i++, j--) {
            while (i < j && !set.contains(arr[i])) i++;
            while (i < j && !set.contains(arr[j])) j--;
            if (i >= j) break;
            swap(arr, i, j);
        }
        return String.valueOf(arr);
    }

    private void swap(char[] arr, int i, int j) {
        char t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
}

557. 反转字符串中的单词 III easy

给定一个字符串 s,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

java
class Solution {
    public String reverseWords(String s) {
        return Arrays.stream(s.split(" "))
                .map(o -> new StringBuilder(o).reverse())
                .reduce(new StringBuilder(), (a, b) -> a.append(' ').append(b))
                .toString()
                .trim();
    }
}

编解码

394. 字符串解码 mid

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4]的输入。

解法 栈

用栈模拟递归,关键在于递归结果的保存,要想清楚在哪里递归

java
class Solution {
    public String decodeString(String s) {
        Deque<StringBuilder> stack = new ArrayDeque<>();
        Deque<Integer> multiStack = new ArrayDeque<>();
        StringBuilder prefix = new StringBuilder();
        int multi = 0;
        for (char c : s.toCharArray()) {
            if (c >= '0' && c <= '9') {
                multi = multi * 10 + c - '0';
            } else if (c == '[') {
                multiStack.push(multi);
                multi = 0;
                // 递,保存pre
                stack.push(prefix);
                prefix = new StringBuilder();
            } else if (c == ']') {
                // 归,将子串repeat然后拼到pre
                prefix = stack.pop().repeat(prefix, multiStack.pop());
            } else {
                prefix.append(c);
            }
        }
        return prefix.toString();
    }
}

区间编辑

848. 字母移位 mid

有一个由小写字母组成的字符串 s,和一个长度相同的整数数组 shifts。

我们将字母表中的下一个字母称为原字母的 移位 shift() (由于字母表是环绕的, 'z' 将会变成 'a')。

例如,shift('a') = 'b', shift('t') = 'u', 以及 shift('z') = 'a'。 对于每个 shifts[i] = x , 我们会将 s 中的前 i + 1 个字母移位 x 次。

返回 将所有这些移位都应用到 s 后最终得到的字符串 。

java
class Solution {
    public String shiftingLetters(String s, int[] shifts) {
        int n = shifts.length;
        int[] arr = Arrays.copyOf(shifts, n);
        // 后面的累加到前面
        for (int i = n - 2; i >= 0; i--) {
            arr[i] = (arr[i] + arr[i + 1]) % 26;
        }
        StringBuilder sb = new StringBuilder(s);
        for (int i = 0; i < n; i++) {
            char c = sb.charAt(i);
            c = (char) ('a' + (c - 'a' + arr[i]) % 26);
            sb.setCharAt(i, c);
        }
        return sb.toString();
    }
}