zoukankan      html  css  js  c++  java
  • 一道求树中每层乘积的和的算法题

          面试中遇到这样一个算法题,每层拆成父节点的和,最小是1(父节点是1的节点不要再拆了,因为只能拆成0和0,乘积是0,再相加没有意义了),最大是父节点-1。:

          

          我的解法,使用递归求解:

          

    package com.company;
    
    import java.util.Random;
    
    /**
     * 求树中每层乘积的和的算法
     *
     * @Auther: Liu Zhong Jun
     * @Date: Created In 2017/12/24 17:58
     * @Modified By:
     */
    public class TreeSum {
        public static void main(String[] args) {
            System.out.println(sum(100));
        }
        public static long sum(int n) {
            if (n == 1) {
                return 0L;
            }
            int left = random(n);
            int right = n - left;
            return left * right + sum(left) + sum(right);
        }
    
        private static int random(int n) {
            if (n == 1)
                return 0;
            if (n == 2)
                return 1;
            int rand = new Random().nextInt(n);
            if (rand == 0)
                return 1;
            return rand;
        }
    }

          当然,以上无疑是正确的,但是算法复杂度是O(n2),是面试官推导的。惭愧。

          其实,这里有个规律,就是子节点无论怎么拆,结果(和)都是一样的。(不信你试试)

          要想提高算法的效率,我们可以变通一下,看下面的树:

          大家发现规律了吧,只要计算右边顶点的和就可以了,这样将递归和里面的乘法转换等差数列了。既简单,效率又高。

          等差数列的计算公式是:

          

          时间复杂度是:longn/2

  • 相关阅读:
    Java ee第七周作业
    Java ee第六周作业
    Java ee第五周作业
    Java ee第四周作业
    Java ee第三周作业
    第二周作业-web后台应用开发与xml
    Java ee第一周的作业
    在团队项目中我对自己的总结
    两人合作,黄金点游戏
    c语言实现wc功能
  • 原文地址:https://www.cnblogs.com/feiyujun/p/8098820.html
Copyright © 2011-2022 走看看