二叉樹尋路——Java版
題目:
在一棵無限的二叉樹上,每個節點都有兩個子節點,樹中的節點 逐行 依次按 “之” 字形進行標記。
如下圖所示,在奇數行(即,第一行、第三行、第五行……)中,按從左到右的順序進行標記;
而偶數行(即,第二行、第四行、第六行……)中,按從右到左的順序進行標記。
給你樹上某一個節點的標號 label
,請你返回從根節點到該標號爲 label
節點的路徑,該路徑是由途經的節點標號所組成的。
示例 1:
輸入:label = 14
輸出:[1,3,4,14]
示例 2:
輸入:label = 26
輸出:[1,2,6,10,26]
提示:
1 <= label <= 10^6
題解:這個題目的我的解題思路是找規律(找規律是因爲和2019年河南ACM省賽的第J題有些相像),通過觀察我們可以發現奇數層順序都是正序的,偶數層的順序都是倒序的,但是對於它們來說尋找他們的父節點找到的都是錯誤的(一個父節點加入爲n,兩個子節點爲2n + 1和2n),這個時候我們需要撥正反亂,假如輸入的是26(奇數層),原本的子節點應該是13,但是現在是10,但是我們現在只知道13,我們需要找出來現在佔了13位置的是誰?13 - 8 + 1 = 6求出的是原來13所在的位置,8 - 6 = 2求出的倒序後對應值原來的位置,8 + 2 = 10 則是倒序後對應值原來的位置的值,則求出的是原來13位置的值變成了10。假如輸入的是14(偶數層),原本的子節點是7,但是現在是4,我們將14所在層的順序當作正序,則它的上一層就是反序,同樣7 - 4 + 1 = 4求出的是7所在的位置,4 - 4 = 0求出的是求出的倒序(相對的)後對應值原來的位置,4 + 0= 4則是倒序(相對的)後對應值原來的位置的值,則求出的是原來7位置的值變成了4。我們可以總結出這樣的公式:
num爲父節點層的最小值,也是2的方,label是我們的輸入值。
假如label爲26
首先它的原父節點爲label/2,label/2 - num + 1 = 6求出的是原來13所在的位置
,num - (label/2 - num + 1) = 2求出的倒序後對應值原來的位置,
num + (num - (label/2 - num + 1)) = 10 則是倒序後對應值原來的位置的值,
則求出的是原來13位置的值變成了10得 3 * num - label / 2 - 1
源代碼:
class Solution {
public List<Integer> pathInZigZagTree(int label) {
String binary = Integer.toBinaryString(label);
int count = binary.length() - 1;
int[] ans = new int[count + 1];
ans[count] = label;
for (int i = ans.length - 2; i >= 0; i--) {
int num = 1 << (count - 1);
ans[i] = 3 * num - label / 2 - 1;
label = ans[i];
count--;
}
List<Integer> list = new ArrayList<Integer>();
for (int i : ans) {
list.add(i);
}
return list;
}
}
在求偶數層的時候我們也可以通過從輸入值的位置找到原來所在此位置的值,再從原位置的值找到父節點,這樣的話只能用if語句分別討論了,有些麻煩。例子:比如輸入值爲14,14 - 8 + 1 = 7求出的是原來13所在的位置,8 - 7 = 1求出的倒序後對應值原來的位置,8 + 1 = 9 則是倒序後對應值原來的位置的值,9 / 2 = 4,則14對應的父節點爲4。
如果文中我的理解有偏差或者錯誤,請閱讀者評論指出,不勝感激。