算法——小球下落(二叉樹)

問題描述 :

    有一棵二叉樹,最大深度爲D,且所有葉子的深度都相同。所有結點從上到下從左到右 編號爲1, 2, 3,…, 2D-1。在結點1處放一個小球,它會往下落。每個內結點上都有一個開關, 初始全部關閉,當每次有小球落到一個開關上時,狀態都會改變。當小球到達一個內結點時,如果該結點上的開關關閉,則往左走,否則往右走,直到走到葉子結點。

如圖所示:


樣式輸入:

4 2
3 4
10 1
2 2
8 128
16 12345


樣式輸出:

12
7
512
3
255
36358

解題思路:

    本題原先採用利用數組存儲二叉樹節點,但是會造成大量空間浪費。

    所以我們假設只有2個球,深度2第一個球很明顯就落在1號根節點的左子樹上,第二個球落在1號根節點的右子樹上。因此可以推論,只要看球個數的奇偶性,便可以計算出它最終是落在哪個子樹上。如果球的個數是奇數,便落在(num+1)/2的左子樹上。如果球的個數是偶數,便落在num/2的右子樹上。

實現:

import java.util.Scanner;

/**
 * 小球落地問題
 *
 * @Classname BallFall
 * @Description TODO
 * @Date 2019/8/17 14:50
 * @Created zzf
 */
public class BallFall {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //深度
        int depth = sc.nextInt();
        //第num個球
        int num = sc.nextInt();
        //初始化
        int data = 1;
        //計算層數爲1~dapth-1
        for (int i = 1; i <= depth - 1; i++) {
            //如果有餘數則這個球在左邊,否則在右邊
            if (num % 2 == 1) {
                //計算,因爲在左邊*2
                data *= 2;
                //計算下一個標號的位置
                num = (num + 1) / 2;
            } else {
                //計算,右邊比左邊大1
                data = data * 2 + 1;
                num /= 2;
            }
//            System.out.println(data);
        }
        System.out.println(data);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章