【刷題打卡】day11-二叉樹
阿新 • • 發佈:2021-01-16
從現在開始每天至少刷一道題。
題庫:lintcode
有些題目連結打不開,需要許可權,那大家就去九章演算法參考答案裡找找。
Insert Node in a Binary Search Tree
題目連結
難度:easy
演算法:二分法
解題思路
插入一定在樹的葉子節點上。如果target大於節點值,往右子樹搜尋;否則,往左子樹搜尋。當搜尋null時,說明可以找到可以插入的位置。儲存插入位置之前的那個父節點。如果該父節點大於target,target是父節點的左節點,否則是右節點。
時間複雜度:O(logn)
空間複雜度:O(1)
解法
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/*
* @param root: The root of the binary search tree.
* @param node: insert this node into the binary search tree
* @return: The root of the new binary search tree.
*/
public TreeNode insertNode(TreeNode root, TreeNode node) {
// write your code here
if(root == null){
return node;
}
TreeNode curr = root;
TreeNode last = null;
while(curr != null){
last = curr;
if(curr.val > node.val){
curr = curr.left;
}else{
curr = curr.right;
}
}
if(last != null){
if(last.val > node.val){
last.left = node;
}else{
last.right = node;
}
}
return root;
}
}
Remove Node in Binary Search Tree
題目連結
難度:hard
演算法:二分法
解題思路
先找出target的節點以及其父節點。然後用target左子樹的最大值或者右子樹的最小值替換target節點。注意,當target節點就是根節點的時候,根節點沒有父節點,所以我們要給根節點造一個父節點。
具體步驟
- 從根節點出發,如果target value 大於根節點的值,那麼往右子樹繼續搜尋。如果小於,往左子樹搜尋。當等於的時候,停止搜尋,返回當前節點的父節點
- 假設用target左子樹的最大值替換target節點,用右子樹的最小值也行,只考慮其中一種方案。如果target的左節點為null,那麼parent直接指向target的右節點。否則,在target的左子樹查詢最大節點及其父節點,也就是在最右邊。找到後,將父值指向最大節點的左節點(因為右節點已經是空了),將target替換成最大節點。通過最大節點的左右節點指向target的左右節點。
時間複雜度:O(logn), 查詢節點通過二分進行的,O(logn);刪除節點也是二分,其實一直往右邊。O(logn)
空間複雜度:O(1)
解法
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/*
* @param root: The root of the binary search tree.
* @param value: Remove the node with given value.
* @return: The root of the binary search tree after removal.
*/
public TreeNode removeNode(TreeNode root, int value) {
// write your code here
TreeNode dummy = new TreeNode(0);
dummy.left = root;
TreeNode parent = findNode(dummy, root, value);
TreeNode target;
if(parent.left != null && parent.left.val == value){
target = parent.left;
}else if(parent.right != null && parent.right.val == value){
target = parent.right;
}else{
return dummy.left;
}
// System.out.printf("%d %d\n", parent.val, target.val);
//replace target node
deleteNode(parent, target);
return dummy.left;
}
private TreeNode findNode(TreeNode parent, TreeNode node, int value){
if(node == null){
return parent;
}
if(node.val == value){
return parent;
}
while(node != null){
if(node.val > value){
parent = node;
node = node.left;
}else if(node.val < value){
parent = node;
node = node.right;
}else{
break;
}
}
return parent;
}
private void deleteNode(TreeNode parent, TreeNode node){
if(node.left == null){
if(parent.left == node){
parent.left = node.right;
}else{
parent.right = node.right;
}
}
else{
//replace node with the largest value on the left
//node 3
//parent 5
TreeNode tmp = node.left; //2
TreeNode father = node; //3
while(tmp.right != null){
father = tmp;
tmp = tmp.right;
}
//remove the largest value
if(father.left == tmp){
father.left = tmp.left; //null
}else{
father.right = tmp.left;
}
// System.out.printf("%d %d\n",parent.left.val, node.val);
if(parent.left == node){
System.out.print(tmp.val);
parent.left = tmp; //2
}else{
parent.right = tmp;
}
tmp.left = node.left; //null
tmp.right = node.right; //4
}
}
}