剑指 Offer 05. 替换空格

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


StringBuilder 解法

  1. class Solution {
  2. public String replaceSpace(String s) {
  3. StringBuilder sb = new StringBuilder(s);
  4. char[] chars = s.toCharArray();
  5. for (char c : chars) {
  6. if (' ' == c) {
  7. sb.append("%20");
  8. }else {
  9. sb.append(c);
  10. }
  11. }
  12. return sb.toString()
  13. }
  14. }

双指针 不用 StringBuilder 的解法
思路:

  • 首先扩充数组到每个空格替换成 “%20” 之后的大小。
  • 然后从后向前替换空格,也就是双指针法,过程如下:

剑指 Offer - 图1

  1. class Solution {
  2. public String replaceSpace(String s) {
  3. char[] chars = s.toCharArray();
  4. int emptySize = 0;
  5. for (char c : chars) {
  6. if (' ' == c) {
  7. emptySize++;
  8. }
  9. }
  10. // 扩充数组到每个空格替换成 "%20" 之后的大小
  11. char[] newChars = Arrays.copyOf(chars, chars.length + 2 * emptySize);
  12. // ===============双指针的代码逻辑=================
  13. // newChars 数组中索引位置
  14. // [0, i] 为未处理的字符,
  15. // (i, j) 为不需要的字符,
  16. // [j,newChars.length - 1) 为处理后的字符
  17. int i = chars.length - 1;
  18. int j = newChars.length - 1;
  19. while (i >= 0) {
  20. if (newChars[i] == ' ') {
  21. newChars[j] = '0';
  22. newChars[j - 1] = '2';
  23. newChars[j - 2] = '%';
  24. j -= 3;
  25. } else {
  26. newChars[j] = newChars[i];
  27. j -= 1;
  28. }
  29. i--;
  30. }
  31. return new String(newChars);
  32. }
  33. }

剑指 Offer 55 - II. 平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。


思路:左程云的二叉树递归套路


  1. class Solution {
  2. public boolean isBalanced(TreeNode root) {
  3. Info info = isBalanced1(root);
  4. return info.isBalanced;
  5. }
  6. public Info isBalanced1(TreeNode treeNode) {
  7. if (treeNode == null) {
  8. return new Info(true, 0);
  9. }
  10. Info lInfo = isBalanced1(treeNode.left);
  11. Info rInfo = isBalanced1(treeNode.right);
  12. //加工出以 treeNode 为头节点的树的 Info 信息返回
  13. Info info = new Info();
  14. info.height = Math.max(lInfo.height, rInfo.height) + 1;
  15. // 列出答案所有的可能性
  16. if (lInfo.isBalanced && rInfo.isBalanced && Math.abs(lInfo.height - rInfo.height) <= 1) {
  17. info.isBalanced = true;
  18. } else {
  19. info.isBalanced = false;
  20. }
  21. return info;
  22. }
  23. // 以 treeNode 为头节点的左子树和右子树需要提供的信息
  24. class Info {
  25. // 树是否平衡
  26. Boolean isBalanced;
  27. // 树的高度
  28. int height;
  29. public Info() {
  30. }
  31. public Info(Boolean isBalanced, int height) {
  32. this.isBalanced = isBalanced;
  33. this.height = height;
  34. }
  35. }
  36. }


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

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


在一个数组上操作字符解法
思路

  1. 反转区间为前 n 的子串
  2. 反转区间为 n 到末尾的子串
  3. 反转整个字符串

    1. class Solution {
    2. public String reverseLeftWords(String s, int n) {
    3. StringBuilder sb = new StringBuilder(s);
    4. // 反转区间为前 n 的子串
    5. reverseString(sb, 0, n - 1);
    6. // 反转区间为 n 到末尾的子串
    7. reverseString(sb, n, s.length() - 1);
    8. // 反转整个字符串
    9. sb.reverse();
    10. return sb.toString();
    11. }
    12. public void reverseString(StringBuilder sb, int startIndex, int endIndex) {
    13. int i = startIndex;
    14. int j = endIndex;
    15. while (i < j) {
    16. char temp = sb.charAt(i);
    17. sb.setCharAt(i++, sb.charAt(j));
    18. sb.setCharAt(j--, temp);
    19. }
    20. }
    21. }