JAVA 树状递归变换循环

主要思路:为避免递归函数的参数、状态积压在栈上,最终耗尽栈空间,参考了cps变换实现的思路。网上给出的cps尾调用,尾递归形成的链式函数,实质上就是返回部分结果和下一循环要执行的方法,个人感觉在阅读性和抽象能力不够友好,所以,改为记录部分结果,以及下一循环的节点值。

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import java.util.LinkedList;

public class MethodUtil {
    private static class Entry<P, V> {
        LinkedList<P> nodeList = new LinkedList<>();
        V tempValue = null;
    }

    public static <P, V> V cps(P original, INodeManager<P, V> nv) {
        Entry<P, V> entry = new Entry<>();
        entry.tempValue = nv.addNodeValue(original, entry.tempValue);
        nv.addChildNode(original, entry.nodeList);
        while (entry.nodeList.size() > 0) {
            P n = entry.nodeList.pollFirst();
            entry.tempValue = nv.addNodeValue(n, entry.tempValue);
            nv.addChildNode(n, entry.nodeList);
        }
        return entry.tempValue;
    }

    public interface INodeManager<P, V> {
        @Nullable
        V addNodeValue(@Nullable P node, @Nullable V value);

        void addChildNode(@Nullable P node, @NonNull LinkedList<P> nodeList);
    }
}

使用示例:
爬楼梯问题:可以一次上1级台阶,也可以一次上2级台阶,所以当只有1级台阶时有1种爬楼梯方式,当只有2级台阶时有2种爬楼梯方式;即有f(1)=1,f(2)=2。问当有n级台阶时有多少种爬楼梯方式?
这是一道经典当动态规划算法题,由于最后一步可能是上了1级台阶,也可能是上了2级台阶,所以有f(n)=f(n-1)+f(n-2);
常规解法:

 public int step(int count) {
        if (count == 1) {
            return 1;
        } else if (count == 2) {
            return 2;
        } else {
            return step(count - 1) + step(count - 2);
        }
    }

使用上面当转换来做:

public int step(int index) {
        Integer result = MethodUtil.cps(index, new INodeManager<Integer, Integer>() {
            @Override
            public Integer addNodeValue(Integer node, Integer value) {
                if (node == null) {
                    return value;
                } else if (node == 1) {
                    if (value == null) {
                        return 1;
                    } else {
                        return value + 1;
                    }
                } else if (node == 2) {
                    if (value == null) {
                        return 2;
                    } else {
                        return value + 2;
                    }
                }
                return value;
            }

            @Override
            public void addChildNode(Integer node, LinkedList<Integer> nodeList) {
                if (node != null && node > 2) {
                    nodeList.add(node - 1);
                    nodeList.add(node - 2);
                }
            }
        });
        return result == null ? 0 : result;
    }

此方法虽然避免了使用递归,但是需要创建许多的LinkedList中的Node对象,也是一笔不小的开销,目前没想到太好的解决方法。
2020-06-30

posted @ 2020-10-09 18:28  FirstLetterZ  阅读(186)  评论(0)    收藏  举报