22.1.20. 暴力递归

22.1.20. 暴力递归

1.关键

  • 暴力递归的关键在于找到一种决策,即一种试的方法(例如从左到右依次试或者按某个影响问题的因素来试),寻找决策的原则应按照可变参数形式简单(尽量不用栈,队列等形式的可变参数,数量少的原则进行。

2.例子

1)汉诺塔问题(三根柱子分别命名为Left,Mid,Right,目的是从Left->Right)。
  • 汉诺塔问题的决策分三步:

—把1~i-1位置上的盘子从Left->Mid;

—把i位置上的盘子从Left移向Right(打印);

—把1~i-1位置上的盘子从Mid->Right(递归);

  • code:

    public static void h(int n,int m,String Left,String Mid, String Right)
{
if(n == 1)
{
System.out.println("move "+m+" from "+Left+" to "+Right) ;
}
else
{
h(n-1,m-1,Left,Right,Mid);
h(1,m,Left,Mid,Right);
h(n-1,m-1,Mid,Left,Right);
}
}

public static void main(String[] args)
{
h(3,3,"Left","Mid","Right");
}
  • 结果:

move 1 from Left to Right
move 2 from Left to Mid
move 1 from Right to Mid
move 3 from Left to Right
move 1 from Mid to Left
move 2 from Mid to Right
move 1 from Left to Right
2)求一个字符串的全部子序列。
  • 决策:从左到右依次决策要或不要,从而能得到一棵满二叉树,遍历这棵满二叉树可得到全部的子序列。

  • code:

    public static void function(String str) {
char[] chs = str.toCharArray();
process(chs, 0, new ArrayList<Character>());
}

public static void process(char[] chs, int i, List<Character> res) {
if(i == chs.length) {
printList(res);//打印
}
List<Character> resKeep = copyList(res);
resKeep.add(chs[i]);
process(chs, i+1, resKeep);
List<Character> resNoInclude = copyList(res);//复制
process(chs, i+1, resNoInclude);
}
  • 一个省空间的优化方法(String型参数的复用)

  • code:

    public static void printAllSubsquence(String str) {
char[] chs = str.toCharArray();
process(chs, 0);
}

public static void process(char[] chs, int i) {
if (i == chs.length) {
System.out.println(String.valueOf(chs));
return;
}
process(chs, i + 1);//相较于上个方法少了List空间的开辟。
char tmp = chs[i];
chs[i] = 0;
process(chs, i + 1);
chs[i] = tmp;
}
3)只用递归的方式不开辟额外的空间逆序一个栈。
  • code:

    public static void main(String[] args)
{
Stack<Integer> stack = new Stack<Integer>();
stack.add(1);
stack.add(2);
stack.add(3);
for(int cur:stack)
System.out.println(cur) ;
ReverseStack(stack);
for(int cur:stack)
System.out.println(cur) ;
}

public static int GetBottomOne(Stack<Integer> s)
{
int temp = s.pop();
if(s.isEmpty())
return temp;
else
{
int last = GetBottomOne(s);
s.push(temp);
return last;
}
}

public static void ReverseStack(Stack<Integer> s)
{
if(s.isEmpty())
return;
else
{
int i = GetBottomOne(s);
ReverseStack(s);
s.push(i);
}
}
  • 结果:

1
2
3
3
2
1

 

posted @ 2022-01-20 20:33  张满月。  阅读(398)  评论(0编辑  收藏  举报