1.1、題目1
劍指 Offer 07. 重建二叉樹
1.2、解法
註釋解法。
1.3、程式碼
class Solution {
int[] preorder;
HashMap<Integer, Integer> map = new HashMap<>();
// 前序遍歷 preorder: 根 -- 左 -- 右 第一個肯定是根節點
// 中序遍歷 inorder: 左 -- 根 -- 右
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder = preorder;
for(int i = 0; i < inorder.length; i++){
map.put(inorder[i], i);
}
return rebuild(0, 0, inorder.length - 1);
}
// pre_root_index : 根節點 在 前序遍歷中的下標
// in_left_index: 該節點在中序遍歷中的左邊界
// in_right_index: 該節點在中序遍歷中的右邊界
public TreeNode rebuild(int pre_root_index, int in_left_index, int in_right_index){
if(in_left_index > in_right_index) return null;
// 根節點在中序遍歷中的位置:in_root_index
int in_root_index = map.get(preorder[pre_root_index]);
// 建立一個根節點
TreeNode node = new TreeNode(preorder[pre_root_index]);
// 尋找node的左節點:
// 在前序遍歷中的位置就是 根節點的下標 + 1(右邊一個單位)
// 在中序遍歷中的位置就是: 1. 左邊界不變,2. 右邊界就是根節點的左邊一個單位 in_root_index - 1
node.left = rebuild(pre_root_index + 1, in_left_index, in_root_index - 1);
// 尋找node的右節點:
// 在前序遍歷中的位置就是 根節點的下標 + 左子樹長度 + 1
// 在中序遍歷中的位置就是: 1. 左邊界在根節點的右邊一個單位 in_root_index + 1, 2. 右邊界不變
node.right = rebuild(pre_root_index + in_root_index - in_left_index + 1, in_root_index + 1, in_right_index);
return node;
}
}
2.1、題目2
劍指 Offer 16. 數值的整數次方
2.2、解法
分類討論,判斷內容,通過將數拆開兩半來減少效能消耗(容易棧溢位)
2.3、程式碼
class Solution {
public double myPow(double x, int n) {
if(n<0) return 1/(x*myPow(x,-n-1)) ;
else if(n==0) return 1;
else if(n==1) return x;
else{
double res=myPow(x,n/2);
return res*res*myPow(x,n%2);
}
}
}
3.1、題目3
劍指 Offer 33. 二叉搜尋樹的後序遍歷序列
3.2、解法
遞迴開始判斷,找到第一個大於根節點的值,然後找出左子樹和右子樹的兩個區間,
通過遞迴再次判斷
3.3、程式碼
class Solution {
public boolean verifyPostorder(int[] postorder) {
return recur(postorder,0,postorder.length - 1);
}
boolean recur(int[] postorder, int start, int end){
if(start >= end) return true;
int temp = start;
// 找到右子樹結點第一次出現的地方。(或者說是遍歷完整棵左子樹)
for(int i = start; i <= end; ++i){
if(postorder[i] < postorder[end]){
temp = i;
}
else break;
}
int rightTreeNode = temp + 1; // 後序遍歷右子樹時會訪問的第一個結點的下標。
// 驗證右子樹所有結點是否都大於根結點。
for(int i = rightTreeNode; i <= end; ++i){
if(postorder[i] > postorder[end])
++rightTreeNode;
}
return rightTreeNode == end && recur(postorder,start,temp) && recur(postorder,temp + 1,end - 1);
}
}