暴力递归
汉诺塔问题
打印n层汉诺塔从最左边到最右边的的全部过程
public class Hanoi{
public static void hanoi1(int n){
leftToRight(n);
}
private static void leftToRight(int n){
if (n == 1){
System.out.println("Move 1 from left to right");
return;
}
leftToMid(n-1);
System.out.println("Move "+ n+" from left to right");
midToRight(n-1);
}
private static void midToRight(int n){
if (n ==1){
System.out.println("Move 1 from mid to right");
return;
}
midToLeft(n-1);
System.out.println("Move "+n+" from mid to right");
leftToRight(n-1);
}
private static void midToLeft(int n){
if (n ==1){
System.out.println("Move 1 from mid to left");
return;
}
midToRight(n-1);
System.out.println("Move "+n+" from mid to left");
rightToLeft(n-1);
}
private static void rightToLeft(int n){
if (n == 1){
System.out.println("Move 1 from right to left");
return;
}
rightToMid(n-1);
System.out.println("Move "+n+" from right to left");
midToLeft(n-1);
}
private static void rightToMid(int n){
if (n == 1){
System.out.println("Move 1 from right to mid");
return;
}
rightToLeft(n-1);
System.out.println("Move "+n+" from right to mid");
leftToMid(n-1);
}
private static void leftToMid(int n){
if (n ==1){
System.out.println("Move 1 from left to mid");
return;
}
leftToRight(n-1);
System.out.println("Move "+n+" from left to mid");
rightToMid(n-1);
}
public static void hanoi2(int n){
if (n >0){
func(n,"left","right","mid");
}
}
private static void func(int n,String from,String to,String other){
if (n ==1){
System.out.println("Move 1 from "+from+" to "+to);
return;
}
func(n-1,from,other,to);
System.out.println("Move "+n+" from "+from+" to "+to);
func(n-1,other,to,from);
}
public static void main(String[] args){
int n =3;
//hanoi1(n);
hanoi2(n);
}
}
子序列问题
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class PrintAllSubsquences{
//打印一个字符串的全部子序列
public static List<String> subs(String s){
char[] str = s.toCharArray();
String path = "";
List<String> ans = new ArrayList<>();
process1(str,0,ans,path);
//process2(str,0,str.length,ans);
return ans;
}
//打印一个字符串的全部子序列,要求不要出现重复字面值的子序列
public static List<String> subsNoRepeat(String s){
char[] str = s.toCharArray();
String path = " ";
HashSet<String> set = new HashSet<>();
process2(str,0,set,path);
List<String> ans = new ArrayList<>();
for (String cur :set){
ans.add(cur);
}
return ans;
}
// str 固定参数
// 来到了str[index]字符,index是位置
// str[0..index-1]已经走过了!之前的决定,都在path上
// 之前的决定已经不能改变了,就是path
// str[index....]还能决定,之前已经确定,而后面还能自由选择的话,
// 把所有生成的子序列,放入到ans里去
private static void process1(char[] str,int index,List<String> ans,String path){
if (index == str.length){
ans.add(path);
return;
}
process1(str,index+1,ans,path);
process1(str,index+1,ans,path+String.valueOf(str[index]));
}
private static void process2(char[] str,int index,HashSet<String> set, String path){
if (index == str.length){
set.add(path);
return;
}
String no = path;
process2(str,index + 1,set,no);
String yes = path+String.valueOf(str[index]);
process2(str,index + 1,set,yes);
}
public static void main(String[] args){
String test = "acccc";
List<String> ans1 = subs(test);
List<String> ans2 = subsNoRepeat(test);
for (String str : ans1) {
System.out.println(str);
}
System.out.println("=================");
for (String str : ans2) {
System.out.println(str);
}
System.out.println("=================");
}
}
字符串排列
import java.util.ArrayList;
import java.util.List;
public class PrintAllPermutations{
//打印一个字符串的全部排列
public static List<String> permutation1(String s){
List<String> ans = new ArrayList<>();
if (s == null || s.length() == 0){
return ans;
}
ArrayList<Character> rest = new ArrayList<>();
char[] str = s.toCharArray();
for (char ch : str){
rest.add(ch);
}
String path = "";
process1(rest,path,ans);
return ans;
}
private static void process1(ArrayList<Character> rest,String path,List<String> ans){
if (rest.isEmpty()){
ans.add(path);
}else {
int N = rest.size();
for (int i = 0; i < N; i++) {
char cur = rest.get(i);
rest.remove(i);
process1(rest,path+cur,ans);
rest.add(i,cur);
}
}
}
public static List<String> permutation2(String s){
List<String> ans = new ArrayList<>();
if (s == null || s.length() == 0){
return ans;
}
char[] str = s.toCharArray();
process2(str,0,ans);
return ans;
}
private static void process2(char[] str,int index,List<String> ans){
if (index == str.length){
ans.add(String.valueOf(str));
}else {
for (int i = index; i < str.length; i++) {
swap(str,index,i);
process2(str,index+1,ans);
swap(str,index,i);
}
}
}
private static void swap(char[] str,int index,int i){
char tmp = str[index];
str[index] = str[i];
str[i] = tmp;
}
打印一个字符串的全部排列,要求不要出现重复的排列
public static List<String> permutation3(String s){
List<String> ans = new ArrayList<>();
if (s == null || s.length() == 0){
return ans;
}
char[] str = s.toCharArray();
process3(str,0,ans);
return ans;
}
private static void process3(char[] str,int index,List<String> ans){
if (index == str.length){
ans.add(String.valueOf(str));
}else {
boolean[] visited = new boolean[256];
for (int i = index; i <str.length ; i++) {
if (!visited[str[i]]){
visited[str[i]] = true;
swap(str,index,i);
process3(str,index+1,ans);
swap(str,index,i);
}
}
}
}
}
逆序一个栈,不能有额外的数据结构
import java.util.Stack;
public class ReverseStackUsingRecursive{
//给你一个栈,请你逆序这个栈,
//不能申请额外的数据结构,
// 只能使用递归函数。 如何实现?
public static void reverse(Stack<Integer> stack){
if (stack.isEmpty()){
return;
}
int i = f(stack); //取得当前栈的栈底
reverse(stack);
stack.push(i);
}
// 栈底元素移除掉
// 上面的元素盖下来
// 返回移除掉的栈底元素
private static int f(Stack<Integer> stack){
int result = stack.pop();
if (stack.isEmpty()){
return result;
}else {
int last = f(stack);
stack.push(result);
return last;
}
}
public static void main(String[] args) {
Stack<Integer> test = new Stack<Integer>();
test.push(1);
test.push(2);
test.push(3);
test.push(4);
test.push(5);
reverse(test);
while (!test.isEmpty()) {
System.out.println(test.pop());
}
}
}
-----from 左程云算法课