Binary Tree
文章目录
- Binary Tree
- leetcode98. Validate Binary Search Tree
- leetcode104. Maximum Depth of Binary Tree
- leetcode111. Minimum Depth of Binary Tree
- leetcode110. Balanced Binary Tree
- leetcode108. Convert Sorted Array to Binary Search Tree
- leetcode109. Convert Sorted List to Binary Search Tree
- leetcode124. Binary Tree Maximum Path Sum
- leetcode157. Binary Tree Upside Down $
leetcode98. Validate Binary Search Tree
题目链接
题目:给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
思路: 按照中序遍历每个节点,并把值保存在list中,如果有序则返回true。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
List<Integer> list = new ArrayList<>();
public boolean isValidBST(TreeNode root) {
//二叉查找树,按照中序遍历 它应该是有序的
search(root);
int len = list.size();
for(int i = 1; i < len; i++){
if(list.get(i - 1) >= list.get(i)){
return false;
}
}
return true;
}
public void search(TreeNode root){
if(root != null){
search(root.left);
list.add(root.val);
search(root.right);
}
}
}
leetcode104. Maximum Depth of Binary Tree
题目链接
题目:给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3 / \ 9 20 / \ 15 7
return its depth = 3.
思路: 比比左子树和右子树哪个高,然后返回较高的那个即可。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root != null){
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return (left > right ? left : right)+ 1;
}
return 0;
}
}
或者
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root != null){
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
return 0;
}
}
leetcode111. Minimum Depth of Binary Tree
题目链接
题目:
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3 / \ 9 20 / \ 15 7
返回它的最小深度 2.
思路: 首先要明确,如果该节点是叶子节点,则返回1,若该节点的一个子树为空 另一个子树非空,在需要返回非空子树的深度,若左右子树都非空,则比左子树和右子树哪个低,然后返回较低的那个即可。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int minDepth(TreeNode root) {
if(root == null){
return 0;
}
if(root.left == null){
return minDepth(root.right) + 1;
}
if(root.right == null){
return minDepth(root.left) + 1;
}
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
}
}
leetcode110. Balanced Binary Tree
题目链接
题目:给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例 1:
3 / \ 9 20 / \ 15 7
给定二叉树 [3,9,20,null,null,15,7]
返回true
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
1 / \ 2 2 / \ 3 3 / \ 4 4
返回 false 。
思路: 求出左右子树的高度,然后比较相差是否大于1即可
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
if(root != null){
int left = getHeight(root.left);
int right = getHeight(root.right);
if(Math.abs(left - right) > 1){
return false;
}
return isBalanced(root.left) && isBalanced(root.right);
}
return true;
}
//获取二叉树高度
public int getHeight(TreeNode root){
if(root != null){
return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
}
return 0;
}
}
leetcode108. Convert Sorted Array to Binary Search Tree
题目链接
题目:
思路:从数组的中间取值作为根节点,左子树是从数组的0到中间位置 - 1,右子树是从中间位置 + 1到末尾,然后递归生成左右子树即可
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return sortedArrayToBST(nums, 0, nums.length - 1);
}
public TreeNode sortedArrayToBST(int[] arr, int start, int end){
if(start > end){
return null;
}
int mid = (start + end) / 2;
TreeNode node = new TreeNode(arr[mid]);
node.left = sortedArrayToBST(arr, start, mid - 1);
node.right = sortedArrayToBST(arr, mid + 1, end);
return node;
}
}
leetcode109. Convert Sorted List to Binary Search Tree
题目链接
题目:给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定的有序链表: [-10, -3, 0, 5, 9],
一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:
0 / \ -3 9 / / -10 5
当然,可以用个数组保存起来,然后像上一道题目一样操作即可。但是那样时间复杂度还是略高。下面是个好方法,由下向上构建。
别人思路:采用自底向上的方法,在这里我们不再需要每次查找中间元素。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private ListNode list;
public TreeNode sortedListToBST(ListNode head) {
int n = 0;
ListNode p = head;
while(p != null){
n++;
p = p.next;
}
list = head;
return sortedListToBST(0, n - 1);
}
private TreeNode sortedListToBST(int start, int end){
if(start > end){
return null;
}
int mid = (start + end) / 2;
TreeNode parent = new TreeNode(list.val);
parent.left = sortedListToBST(start, mid-1);
parent.right = sortedListToBST(mid+1, end);
list = list.next;
return parent;
}
}
leetcode124. Binary Tree Maximum Path Sum
题目链接
题目:给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
示例 1:
输入: [1,2,3]
1 / \ 2 3
输出: 6
示例 2:
输入: [-10,9,20,null,null,15,7]
-10 / \ 9 20 / \ 15 7
输出: 42
思路:其实求一个节点路径最大值,无非有以下四种情形(1)node.val(2)maxPath(node.left) + node.val(3)maxPath(node.right) + node.val(4)maxPath(node.left) + maxPath(node.right) + node.val 采取自下而上的思路进行查找,如果一个节点的左子树或者右子树小于零就直接返回零,不在算上他了。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private int maxPath;
public int maxPathSum(TreeNode root) {
maxPath = Integer.MIN_VALUE;
findMax(root);
return maxPath;
}
public int findMax(TreeNode node){
if(node == null){
return 0;
}
int left = findMax(node.left);
int right = findMax(node.right);
maxPath = Math.max(maxPath, left + right + node.val);
int ret = Math.max(left, right) + node.val;
return ret > 0 ? ret : 0;
}
}
leetcode157. Binary Tree Upside Down $
题目链接
题目:给定一个二叉树,其中所有右节点要么是具有兄弟节点(共享相同父节点的左节点)的叶节点,要么是空的,将其倒过来,并将其转换为一个树,其中原来的右节点转换为左叶节点。返回新的根。
实例1:
给出一个二叉树 {1,2,3,4,5},
1 / \ 2 3 / \ 4 5
返回 [4,5,2,#,#,3,1].
4 / \ 5 2 / \ 3 1
参考
思路:把一棵二叉树上下颠倒一下,而且限制了右节点要么为空要么一定会有对应的左节点。上下颠倒后原来二叉树的最左子节点变成了根节点,其对应的右节点变成了其左子节点,其父节点变成了其右子节点,相当于顺时针旋转了一下。对于一般树的题都会有迭代和递归两种解法,这道题也不例外,那么我们先来看看递归的解法。对于一个根节点来说,我们的目标是将其左子节点变为根节点,右子节点变为左子节点,原根节点变为右子节点,那么我们首先判断这个根节点是否存在,且其有没有左子节点,如果不满足这两个条件的话,直接返回即可,不需要翻转操作。那么我们不停的对左子节点调用递归函数,直到到达最左子节点开始翻转,翻转好最左子节点后,开始回到上一个左子节点继续翻转即可,直至翻转完整棵树
public TreeNode UpsideDownBinaryTree(TreeNode root) {
TreeNode p = root, parent = null, parentRight = null;
while (p != null) {
TreeNode left = p.left;
p.left = parentRight;
parentRight = p.right;
p.right = parent;
parent = p;
p = left;
}
return parent;
}
自底向上的模式
public TreeNode UpsideDownBinaryTree(TreeNode root) {
return dfsBottomUp(root, null);
}
private TreeNode dfsBottomUp(TreeNode p, TreeNode parent) {
if (p == null) return parent;
TreeNode root = dfsBottomUp(p.left, p);
p.left = (parent == null) ? parent : parent.right;
p.right = parent;
return root;
}