二叉树和递归
文章目录
- 二叉树和递归
- 1.二叉树的最大深度
- 2.二叉树的最小深度
- 3.反转二叉树
- 4.相同的树
- 5.完全二叉树的节点个数
- 6.平衡二叉树判断
- 7.路径总和
- 8.路径总和II
- 9.路径总和III
- 10.求根到叶节点数字之和
- 11.二叉搜索树最近公共祖先
- 12.二叉树的最近公共祖先
- 13.二叉搜索树中第k小元素
- 14.删除二叉搜索树中的节点
- 15.将有序数组转为二叉搜索树
1.二叉树的最大深度
public int maxDepth(TreeNode root) {
if(root == null){
return 0;
}
return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1;
}
2.二叉树的最小深度
/**
* 以root节点为根的二叉树的最小深度 = min(以root.left为根的二叉树的最小深度,以root.right为根的二叉树的最小深度) + 1(root节点)
* @param root
* @return
*/
public int minDepth(TreeNode root) {
if(root == null){
return 0;
}else if(root.left != null && root.right != null){
return Math.min(minDepth(root.left),minDepth(root.right)) + 1;
}else if(root.left != null){
return minDepth(root.left) + 1;
}else{
return minDepth(root.right) + 1;
}
}
3.反转二叉树
public TreeNode invertTree(TreeNode root) {
if(root == null)
return null;
invertTree(root.left);
invertTree(root.right);
TreeNode tmpLeft = root.left;
TreeNode tmpRight = root.right;
root.right = tmpLeft;
root.left = tmpRight;
return root;
}
4.相同的树
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q == null)
return true;
if(p == null && q != null)
return false;
if(p != null && q == null)
return false;
if(p.val != q.val)
return false;
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
5.完全二叉树的节点个数
/**
* 二叉树节点数 = 左子树节点数 + 右子树节点数 + 当前节点
* @param root
* @return
*/
public int countNodes(TreeNode root) {
if(root == null)
return 0;
return countNodes(root.left) + countNodes(root.right) + 1;
}
6.平衡二叉树判断
public boolean isBalanced(TreeNode root) {
if(root == null)
return true;
if(Math.abs(getHeight(root.left) - getHeight(root.right)) > 1)
return false;
else
return isBalanced(root.left) && isBalanced(root.right);
}
public int getHeight(TreeNode root) {
if (root == null) {
return 0;
} else {
int lh = getHeight(root.left);
int rh = getHeight(root.right);
return Math.max(lh, rh) + 1;
}
}
7.路径总和
public boolean hasPathSum(TreeNode root, int sum) {
if(root == null)
return false;
if(root.left == null && root.right == null)
return root.val == sum;
if(hasPathSum(root.left,sum - root.val)){
return true;
}
if(hasPathSum(root.right,sum - root.val)){
return true;
}
return false;
}
8.路径总和II
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<List<Integer>> res = new ArrayList<>();
if(root == null)
return res;
if(root.left == null && root.right == null && root.val == sum){
List<Integer> tmp = new ArrayList<>();
tmp.add(root.val);
res.add(tmp);
return res;
}
List<List<Integer>> leftList = pathSum(root.left,sum - root.val);
List<List<Integer>> rightList = pathSum(root.right,sum - root.val);
for(List<Integer> list : leftList){
list.add(0,root.val);
res.add(list);
}
for(List<Integer> list : rightList){
list.add(0,root.val);
res.add(list);
}
return res;
}
9.路径总和III
public int pathSum(TreeNode root, int sum) {
if(root == null)
return 0;
int res = findPath(root,sum);
res += pathSum(root.left,sum);
res += pathSum(root.right,sum);
return res;
}
public int findPath(TreeNode node,int sum){
if(node == null)
return 0;
int res = 0;
if(node.val == sum)
res += 1;
res += findPath(node.left,sum - node.val);
res += findPath(node.right,sum - node.val);
return res;
}
10.求根到叶节点数字之和
int sum = 0;
public int sumNumbers(TreeNode root) {
sumNumbers(0,root);
return sum;
}
private void sumNumbers(int i, TreeNode root) {
if(root == null)
return;
int k = 10 * i + root.val;
if(root.left == null && root.right == null)
sum += k;
sumNumbers(k,root.left);
sumNumbers(k,root.right);
}
11.二叉搜索树最近公共祖先
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
return lca(root, p, q);
}
public TreeNode lca(TreeNode root, TreeNode p, TreeNode q){
if((root.val - p.val) * (root.val - q.val) <= 0){
return root;
}else if(root.val < p.val && root.val < q.val){
return lca(root.right,p,q);
}else{
return lca(root.left,p,q);
}
}
12.二叉树的最近公共祖先
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null)
return null;
if(root == q || root == p)
return root;
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
if(left != null && right != null)
return root;
else if(left != null)
return left;
else
return right;
}
13.二叉搜索树中第k小元素
<Integer> res = new ArrayList<>();
public int kthSmallest(TreeNode root, int k) {
dfs(root,res);
Collections.sort(res);
return res.get(k-1);
}
public void dfs(TreeNode root,List<Integer> list){
if(root == null){
return;
}
dfs(root.left,list);
list.add(root.val);
dfs(root.right,list);
}
14.删除二叉搜索树中的节点
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
if (key < root.val) {
// 待删除节点在左子树中
root.left = deleteNode(root.left, key);
return root;
} else if (key > root.val) {
// 待删除节点在右子树中
root.right = deleteNode(root.right, key);
return root;
} else {
// key == root.val,root 为待删除节点
if (root.left == null) {
// 返回右子树作为新的根
return root.right;
} else if (root.right == null) {
// 返回左子树作为新的根
return root.left;
} else {
// 左右子树都存在,返回后继节点(右子树最左叶子)作为新的根
TreeNode successor = min(root.right);
successor.right = deleteMin(root.right);
successor.left = root.left;
return successor;
}
}
}
private TreeNode min(TreeNode node) {
if (node.left == null) {
return node;
}
return min(node.left);
}
private TreeNode deleteMin(TreeNode node) {
if (node.left == null) {
return node.right;
}
node.left = deleteMin(node.left);
return node;
}
15.将有序数组转为二叉搜索树
public TreeNode sortedArrayToBST(int[] nums) {
if(nums==null)
return null;
return bst(nums,0,nums.length-1);
}
public TreeNode bst(int[] nums,int left,int right) {
if(left>right)
return null;
int mid = left + ((right-left)>>1);
TreeNode root = new TreeNode(nums[mid]);
root.left = bst(nums,left,mid-1);
root.right = bst(nums,mid+1,right);
return root;
}