引言:构造普通的二叉树
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;
}
}
第一部分、验证二叉树的各种性质
1. 求二叉树的深度
leetcode-cn.com/problems/ma…
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
return Math.max(maxDepth(root.left) , maxDepth(root.right)) + 1;
}
}
2. 求二叉树的最小深度
leetcode-cn.com/problems/mi…
class Solution {
public int minDepth(TreeNode root) {
if(root == null) return 0;
int l = minDepth(root.left);
int r = minDepth(root.right);
if(l == 0) return r + 1;
else if(r == 0) return l+1;
return Math.min(l, r) + 1;
}
}
3. 判断是不是平衡二叉树
leetcode-cn.com/problems/ba…
class Solution {
public boolean isBalanced(TreeNode root) {
if(root == null) return true;
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return isBalanced(root.left) && isBalanced(root.right) && Math.abs(left-right) <= 1;
}
int maxDepth(TreeNode root){
if(root == null) return 0;
return Math.max(maxDepth(root.left) , maxDepth(root.right)) + 1;
}
}
4. 翻转二叉树
leetcode-cn.com/problems/in…
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
TreeNode cur = root.left;
root.left = root.right;
root.right = cur;
invertTree(root.left);
invertTree(root.right);
return root;
}
}
5. 判断二叉树是不是对称的
leetcode-cn.com/problems/sy…
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
return isMirror(root.left, root.right);
}
boolean isMirror(TreeNode l , TreeNode r){
if(l == null && r == null) return true;
if(l == null || r == null) return false;
if(l.val != r.val) return false;
return isMirror(l.left , r.right) && isMirror(l.right , r.left);
}
}
6. 判断二叉树是不是一样的
leetcode-cn.com/problems/sa…
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q == null) return true;
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);
}
7. 判断二叉树是不是另一颗二叉树的子树
leetcode-cn.com/problems/su…
class Solution {
public boolean isSubtree(TreeNode s, TreeNode t) {
if(s == null) return false;
if(t == null) return true;
return isSame(s , t) || isSubtree(s.left , t) || isSubtree(s.right , t);
}
boolean isSame(TreeNode s , TreeNode t){
if(s == null && t == null) return true;
if(s == null || t == null) return false;
if(s.val != t.val) return false;
return isSame(s.left , t.left) && isSame(s.right , t.right);
}
}
8.二叉树的直径
leetcode-cn.com/problems/di…
class Solution {
int res = 0;
public int diameterOfBinaryTree(TreeNode root) {
if(root == null) return 0;
dfs(root);
return res;
}
int dfs(TreeNode root){
if(root.left == null && root.right == null) return 0;
int leftSize = root.left == null ? 0 : dfs(root.left) + 1;
int rightSize = root.right == null ? 0 : dfs(root.right) + 1;
res = Math.max(res , leftSize + rightSize);
return Math.max(leftSize , rightSize);
}
}
class Solution {
int res = 0;
public int diameterOfBinaryTree(TreeNode root) {
if(root == null) return 0;
dfs(root);
return res;
}
void dfs(TreeNode root){
if(root == null) return;
int l = maxDepth(root.left);
int r = maxDepth(root.right);
res = Math.max(res , l + r);
dfs(root.left);
dfs(root.right);
}
int maxDepth(TreeNode root){
if(root == null) return 0;
return Math.max(maxDepth(root.left) , maxDepth(root.right)) + 1;
}
}
9. 二叉树的最大路径和
leetcode-cn.com/problems/bi…
class Solution {
int res = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
if(root == null) return 0;
dfs(root);
return res;
}
int dfs(TreeNode root){
if(root == null) return 0;
int leftSum = Math.max(0 , dfs(root.left));
int rightSum = Math.max(0 , dfs(root.right));
res = Math.max(res , leftSum + rightSum + root.val);
return Math.max(leftSum , rightSum) + root.val;
}
}
10. 二叉树的最长同值路径
leetcode-cn.com/problems/lo…
class Solution {
int res = 0;
public int longestUnivaluePath(TreeNode root) {
if(root == null) return 0;
dfs(root);
return res;
}
int dfs(TreeNode root){
if(root.left == null && root.right == null) return 0;
int leftSize = root.left == null ? 0 : dfs(root.left)+1;
int rightSize = root.right == null ? 0 : dfs(root.right)+1;
if(root.left == null || root.val != root.left.val) leftSize = 0;
if(root.right == null || root.val != root.right.val) rightSize = 0;
res = Math.max(res , leftSize + rightSize);
return Math.max(leftSize,rightSize);
}
}
11. 二叉树的最近公共祖先
leetcode-cn.com/problems/lo…
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return root;
if(root == p || root == q) return root;
TreeNode l = lowestCommonAncestor(root.left , p , q);
TreeNode r = lowestCommonAncestor(root.right , p , q);
if(l == null) return r;
if(r == null) return l;
return root;
}
}
第二部分、二叉树的遍历问题
1. 二叉树的先序遍历 --中左右
leetcode-cn.com/problems/bi…
class Solution {
List<Integer> res = new ArrayList<>();
public List<Integer> preorderTraversal(TreeNode root) {
if(root == null) return res;
dfs(root , res);
return res;
}
void dfs(TreeNode root , List<Integer> res){
if(root == null) return;
res.add(root.val);
dfs(root.left , res);
dfs(root.right, res);
}
}
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null) return res;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode curNode = stack.pop();
res.add(curNode.val);
if(curNode.right != null) stack.push(curNode.right);
if(curNode.left != null) stack.push(curNode.left);
}
return res;
}
}
2. 二叉树的中序遍历--左中右
leetcode-cn.com/problems/bi…
class Solution {
List<Integer> res = new ArrayList<>();
public List<Integer> inorderTraversal(TreeNode root) {
if(root == null) return res;
dfs(root , res);
return res;
}
void dfs(TreeNode root , List<Integer> res){
if(root == null) return;
dfs(root.left , res);
res.add(root.val);
dfs(root.right, res);
}
}
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null) return res;
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while(!stack.isEmpty() || cur != null){
while(cur != null){
stack.push(cur);
cur = cur.left;
}
TreeNode curNode = stack.pop();
res.add(curNode.val);
cur = curNode.right;
}
return res;
}
}
3. 二叉树的后序遍历--左右中
leetcode-cn.com/problems/bi…
class Solution {
List<Integer> res = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
if(root == null) return res;
dfs(root , res);
return res;
}
void dfs(TreeNode root , List<Integer> res){
if(root == null) return;
dfs(root.left , res);
dfs(root.right, res);
res.add(root.val);
}
}
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
LinkedList<Integer> res = new LinkedList<>();
if(root == null) return res;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode curNode = stack.pop();
res.addFirst(curNode.val);
if(curNode.left != null) stack.push(curNode.left);
if(curNode.right != null) stack.push(curNode.right);
}
return res;
}
}
4. 二叉树的层序遍历
leetcode-cn.com/problems/bi…
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
int count = queue.size();
List<Integer> list = new ArrayList<>();
while(count > 0){
TreeNode curNode = queue.poll();
list.add(curNode.val);
count--;
if(curNode.left != null) queue.add(curNode.left);
if(curNode.right != null) queue.add(curNode.right);
}
res.add(list);
}
return res;
}
}
5. 二叉树的锯齿形遍历
leetcode-cn.com/problems/bi…
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
int count = queue.size();
List<Integer> list = new ArrayList<>();
while(count > 0){
TreeNode curNode = queue.poll();
list.add(curNode.val);
count--;
if(curNode.left != null) queue.add(curNode.left);
if(curNode.right != null) queue.add(curNode.right);
}
if(res.size() % 2 == 1) Collections.reverse(list);
res.add(list);
}
return res;
}
}
6. 二叉树的右视图
leetcode-cn.com/problems/bi…
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
int count = queue.size();
int tem = 0;
while(count > 0){
TreeNode curNode = queue.poll();
tem = curNode.val;
count--;
if(curNode.left != null) queue.add(curNode.left);
if(curNode.right != null) queue.add(curNode.right);
}
res.add(tem);
}
return res;
}
}
7. 判断是不是完全二叉树
leetcode-cn.com/problems/ch…
class Solution {
public boolean isCompleteTree(TreeNode root) {
if(root == null) return true;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
boolean flag = false;
while(!queue.isEmpty()){
TreeNode curNode = queue.poll();
if(curNode == null){
flag = true;
continue;
}
if(flag) return false;
queue.add(curNode.left);
queue.add(curNode.right);
}
return true;
}
}
8.二叉树的最大宽度
leetcode-cn.com/problems/ma…
class Solution {
public int widthOfBinaryTree(TreeNode root) {
if(root == null) return 0;
int res = 1;
LinkedList<TreeNode> queue = new LinkedList<>();
LinkedList<Integer> indexQueue = new LinkedList<>();
queue.add(root);
indexQueue.add(1);
while(!queue.isEmpty()){
int count = queue.size();
int l = indexQueue.peek();
while(count > 0){
TreeNode curNode = queue.poll();
int r = indexQueue.poll();
count--;
res = Math.max(res , r - l + 1);
if(curNode.left != null){
queue.add(curNode.left);
indexQueue.add(r * 2);
}
if(curNode.right != null){
queue.add(curNode.right);
indexQueue.add(r * 2 + 1);
}
}
}
return res;
}
}
9. 二叉树每一行的最大值
leetcode-cn.com/problems/fi…
public List<Integer> largestValues(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
int count = queue.size();
int tem = Integer.MIN_VALUE;
while(count > 0){
TreeNode curNode = queue.poll();
tem = Math.max(tem , curNode.val);
if(curNode.left != null) queue.add(curNode.left);
if(curNode.right != null) queue.add(curNode.right);
count--;
}
res.add(tem);
}
return res;
}
10. 二叉树的序列化和反序列化
leetcode-cn.com/problems/se…
public class Codec {
public String serialize(TreeNode root) {
if(root == null) return "[]";
StringBuilder sb = new StringBuilder();
sb.append("[");
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
TreeNode curNode = queue.poll();
if(curNode != null){
sb.append(curNode.val).append(",");
queue.add(curNode.left);
queue.add(curNode.right);
}else sb.append("null,");
}
sb.deleteCharAt(sb.length()-1);
sb.append("]");
return sb.toString();
}
public TreeNode deserialize(String data) {
if(data.equals("[]")) return null;
String[] nums = data.substring(1 , data.length()-1).split(",");
TreeNode root = new TreeNode(Integer.parseInt(nums[0]));
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
int index = 1;
while(!queue.isEmpty()){
TreeNode curNode = queue.poll();
if(!nums[index].equals("null")){
curNode.left = new TreeNode(Integer.parseInt(nums[index]));
queue.add(curNode.left);
}
index++;
if(!nums[index].equals("null")){
curNode.right = new TreeNode(Integer.parseInt(nums[index]));
queue.add(curNode.right);
}
index++;
}
return root;
}
}