一道求樹中每層乘積的和的算法題
阿新 • • 發佈:2017-12-24
技術 ted creat n) 規律 遞歸 inf static tint
面試中遇到這樣一個算法題,每層拆成父節點的和,最小是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 staticvoid 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 intrandom(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
一道求樹中每層乘積的和的算法題