1. 程式人生 > >一道求樹中每層乘積的和的算法題

一道求樹中每層乘積的和的算法題

技術 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 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

一道求樹中每層乘積的和的算法題