美文网首页
JAVA 树状递归变换循环

JAVA 树状递归变换循环

作者: 周_0717 | 来源:发表于2020-06-30 17:23 被阅读0次

    主要思路:为避免递归函数的参数、状态积压在栈上,最终耗尽栈空间,参考了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

    相关文章

      网友评论

          本文标题:JAVA 树状递归变换循环

          本文链接:https://www.haomeiwen.com/subject/wubxqktx.html