第17节.pptx
暴力递归就是尝试
1,把问题转化为规模缩小了的同类问题的子问题
2,有明确的不需要继续进行递归的条件(base case)
3,有当得到了子问题的结果之后的决策过程
4,不记录每一个子问题的解

题目1:汉诺塔问题

打印n层汉诺塔从最左边移动到最右边的全部过程
16  暴力递归 - 图1

  1. public static void hanoi(int n) {
  2. fromLeftToRight(n);
  3. System.out.println("===================");
  4. process(n, "left", "right", "middle");
  5. }
  6. private static void fromLeftToRight(int n) {
  7. if (n == 1) {
  8. System.out.println("move 1 from left to right");
  9. return;
  10. }
  11. fromLeftToMiddle(n - 1);
  12. System.out.println("move " + n + " from left to right");
  13. fromMiddleToRight(n - 1);
  14. }
  15. private static void fromMiddleToRight(int n) {
  16. if (n == 1) {
  17. System.out.println("move 1 from middle to right");
  18. return;
  19. }
  20. fromMiddleToLeft(n - 1);
  21. System.out.println("move " + n + " from middle to right");
  22. fromLeftToRight(n - 1);
  23. }
  24. private static void fromMiddleToLeft(int n) {
  25. if (n == 1) {
  26. System.out.println("move 1 from middle to left");
  27. return;
  28. }
  29. fromMiddleToRight(n - 1);
  30. System.out.println("move " + n + " from middle to left");
  31. fromRightToLeft(n - 1);
  32. }
  33. private static void fromLeftToMiddle(int n) {
  34. if (n == 1) {
  35. System.out.println("move 1 from left to middle");
  36. return;
  37. }
  38. fromLeftToRight(n - 1);
  39. System.out.println("move " + n + " from left to middle");
  40. fromRightToMiddle(n - 1);
  41. }
  42. private static void fromRightToMiddle(int n) {
  43. if (n == 1) {
  44. System.out.println("move 1 from right to middle");
  45. return;
  46. }
  47. fromRightToLeft(n - 1);
  48. System.out.println("move " + n + " from right to middle");
  49. fromLeftToMiddle(n - 1);
  50. }
  51. private static void fromRightToLeft(int n) {
  52. if (n == 1) {
  53. System.out.println("move 1 from right to left");
  54. return;
  55. }
  56. fromRightToMiddle(n - 1);
  57. System.out.println("move " + n + " from right to left");
  58. fromMiddleToLeft(n - 1);
  59. }
  60. // 将以上递归进行抽象整合
  61. private static void process(int n, String from, String to, String other) {
  62. if (n == 1) {
  63. System.out.println("move " + n + " from " + from + " to " + to);
  64. return;
  65. }
  66. process(n - 1, from, other, to);
  67. System.out.println("move " + n + " from " + from + " to " + to);
  68. process(n - 1, other, to, from);
  69. }

题目2:打印一个字符串的全部子序列

  1. // 返回一个字符串的全部子序列
  2. public static List<String> subSequence(String str) {
  3. if (str == null || str.length() == 0) {
  4. return null;
  5. }
  6. List<String> subString = new ArrayList<>();
  7. char[] chars = str.toCharArray();
  8. process(chars, 0, subString, "");
  9. return subString;
  10. }
  11. private static void process(char[] chars, int index, List<String> ans, String curSubString) {
  12. if (index == chars.length) {
  13. ans.add(curSubString);
  14. return;
  15. }
  16. // 没有要当前位置的字符
  17. process(chars, index + 1, ans, curSubString);
  18. // 要了当前位置的字符
  19. process(chars, index + 1, ans, curSubString.concat(String.valueOf(chars[index])));
  20. }
  21. // 返回一个字面值字符串不重复的全部子序列
  22. public static List<String> subSequenceNoRepeat(String str) {
  23. if (str == null || str.length() == 0) {
  24. return null;
  25. }
  26. HashSet<String> subString = new HashSet<>();
  27. char[] chars = str.toCharArray();
  28. process2(chars, 0, subString, "");
  29. return new ArrayList<>(subString);
  30. }
  31. private static void process2(char[] chars, int index, HashSet<String> ans, String curSubString) {
  32. if (index == chars.length) {
  33. ans.add(curSubString);
  34. return;
  35. }
  36. process2(chars, index + 1, ans, curSubString);
  37. process2(chars, index + 1, ans, curSubString.concat(String.valueOf(chars[index])));
  38. }

题目3:打印一个字符串的全部排列

// 返回一个字符串的全排列

public static List<String> allPermutation(String string) {
    List<String> ans = new ArrayList<>();
    if (string == null || string.length() == 0) {
        return ans;
    }
    char[] str = string.toCharArray();
    List<Character> chars = new ArrayList<>();
    for (char c : str) {
        chars.add(c);
    }
    process(chars, ans, "");
    return ans;
}

private static void process(List<Character> chars, List<String> ans, String curSubString) {
    if (chars.isEmpty()) {
        ans.add(curSubString);
    } else {
        for (int i = 0; i < chars.size(); i++) {
            char cur = chars.get(i);
            chars.remove(i);
            process(chars, ans, curSubString.concat(String.valueOf(cur)));
            chars.add(i, cur);
        }
    }
}

public static List<String> allPermutation2(String string) {
    List<String> ans = new ArrayList<>();
    if (string == null || string.length() == 0) {
        return ans;
    }
    char[] chars = string.toCharArray();

    process2(chars, 0, ans);
    return ans;
}

private static void process2(char[] chars, int index, List<String> ans) {
    if (index == chars.length) {
        ans.add(String.valueOf(chars));
    } else {
        for (int i = index; i < chars.length; i++) {
            swap(chars, i, index);
            process2(chars, index + 1, ans);
            swap(chars, i, index);
        }
    }

}

private static void swap(char[] chars, int i, int j) {
    char tmp = chars[i];
    chars[i] = chars[j];
    chars[j] = tmp;
}

//  去重的全排列 

public static List<String> allPermutation3(String string) {
    List<String> ans = new ArrayList<>();
    if (string == null || string.length() == 0) {
        return ans;
    }
    char[] chars = string.toCharArray();
    process3(chars, 0, ans);
    return ans;
}

private static void process3(char[] chars, int index, List<String> ans) {
    if (index == chars.length) {
        ans.add(String.valueOf(chars));
    } else {
        boolean[] visited = new boolean[256];
        for (int i = index; i < chars.length; i++) {
            // 剪枝 对于重复出现的字符,直接跳过
            if (!visited[chars[i]]) {
                visited[chars[i]] = true;
                swap(chars, i, index);
                process3(chars, index + 1, ans);
                swap(chars, i, index);
            }

        }
    }
}

题目4:逆序栈

给你一个栈,请你逆序这个栈,
不能申请额外的数据结构,
只能使用递归函数。 如何实现?

//给你一个栈,请你逆序这个栈,
//不能申请额外的数据结构,
//只能使用递归函数。 如何实现?

public static <T> void reverseStack(Stack<T> stack) {
    if (stack == null || stack.empty()) {
        return;
    }
    T last = precess(stack);
    reverseStack(stack);
    stack.push(last);
}

private static <T> T precess(Stack<T> stack) {
    T cur = stack.pop();
    if (stack.empty()) {
        return cur;
    } else {
        T last = precess(stack);
        stack.push(cur);
        return last;
    }
}