算法
538. Convert BST to Greater Tree
Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST.
Example 1:
Input: The root of a Binary Search Tree like this:
5
/ \
2 13
Output: The root of a Greater Tree like this:
18
/ \
20 13
解決方案
解決思路:Tree的解決思路優先遞歸,也就是深度優先算法,因爲遞歸的思路是先遍歷到葉子節點,最終會回到Root節點,直接返回就好。如果用Iteration遍歷,也就是廣度優先算法,那麼就要用棧java中用LinkedList去記錄每一層的數據。
這個題目容易理解錯誤,是每個節點要加上目前最大的值。二分查找數最大值是最右的最層葉子節點。
那麼就用一個屬性sum來記錄最大值。遍歷順序爲右 > 中 > 左;最後到右子樹 > 根節點 > 左子樹。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private int sum = 0;
public TreeNode convertBST(TreeNode root) {
if (root != null) {
convertBST(root.right);
sum += root.val;
root.val = sum;
convertBST(root.left);
}
return root;
}
}
筆者爲了方便調試,把樹按照屬性結構打印了出來。思路如下:
- 按照層組裝數據到List row, 一層的數據組裝完成後,放到最終的結果列表中List<List> list。
- 如何判斷是一層呢?用棧LinkedList rowNode來裝這一層的數據,先計算這一層有多少數據int rowSize = rowNode.size();,下一層的數據追加到rowNode的後面,等遍歷數等於rowSize的時候,說明這一層已經結束。
- 處理葉節子,如果是null節子,則存入字符串"null". 如果是節點爲空,則當層輸入爲"null",下一層的左右子樹也要爲"null"。
- 打印輸出,用4個空格(剛好"null"的長度一致)來間隔。最左側間隔爲當前層到總數的距離,比如第一個爲0到size-1.
package common;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode() { }
public TreeNode(int val) {
this.val = val;
}
public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
@Override
public String toString() {
if (this == null) {
return "null";
}
String result = "";
List<String> row = null;
List<List<String>> list = new ArrayList<List<String>>();
LinkedList<TreeNode> rowNode = new LinkedList<>();
rowNode.add(this);
while (!rowNode.isEmpty()) {
int rowSize = rowNode.size();
row = new ArrayList<String>();
int rowCount = rowSize;
int nullCount = 0;
while (rowSize > 0) {
TreeNode current = rowNode.pop();
if (current == null) {
row.add("null");
nullCount++;
} else {
row.add(Integer.toString(current.val));
}
if (current == null || current.left == null) {
rowNode.add(null);
} else {
rowNode.add(current.left);
}
if (current == null || current.right == null) {
rowNode.add(null);
} else {
rowNode.add(current.right);
}
rowSize--;
}
if (nullCount == rowCount) {
break;
}
list.add(row);
}
// print data
String blank = " ";
for (int i = 0; i < list.size(); i ++) {
for (int j = i; j < list.size(); j++) {
// print blank
System.out.print(blank);
}
List<String> rowList = list.get(i);
for (int k = 0; k < rowList.size(); k++) {
System.out.print(rowList.get(k));
System.out.print(blank);
}
System.out.println();
}
//return Arrays.toString(list.toArray());
return super.toString();
}
}
調用代碼
public static void main(String[] args) {
//TreeNode left1 = new TreeNode(2);
//TreeNode right1 = new TreeNode(13);
//
//TreeNode root = new TreeNode(5, left1, right1);
TreeNode left1 = new TreeNode(1);
TreeNode right1 = new TreeNode(3);
TreeNode rootLeft = new TreeNode(2, left1, right1);
TreeNode left2 = new TreeNode(6);
TreeNode right2 = new TreeNode(15);
TreeNode rootRight = new TreeNode(13, left2, right2);
TreeNode root = new TreeNode(5, rootLeft, rootRight);
root.toString();
// 當前類的名字
ConvertBSTToGreaterTree obj = new ConvertBSTToGreaterTree();
TreeNode result = obj.convertBST(root);
result.toString();
}
輸出結果爲:
5
2 13
1 3 6 15
39
44 28
45 42 34 15