LeetCode:树 通过率高的前十道题

关于这前十道题,总结出来的一点就是递归,树的问题递归来写是非常简单,因为递归的话方便回到父节点。

  1. maximum-depth-of-binary-tree

题目描述
求给定二叉树的最大深度,
最大深度是指树的根结点到最远叶子结点的最长路径上结点的数量。

这个就可以直接递归,求整棵树的最大深度可以看出求左右两颗子树的最大深度的问题,这样就把问题划分成了两个子问题。

public static class TreeNode {
		private int val;
		private TreeNode left;
		private TreeNode right;

		TreeNode(int x) {
			this.val = x;
		}
	}

	public static int maxDepth(TreeNode root) {
		if(root == null) {
			return 0;
		}
		if(root.left == null && root.right == null) {
			return 0;
		}
		return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
	}
  1. same-tree

题目描述
给出两个二叉树,请写出一个判断两个二叉树是否相等的函数。
判断两个二叉树相等的条件是:两个二叉树的结构相同,并且相同的节点上具有相同的值。

这个也是可以递归,就是想成判断两棵树是否相等,就去判断他的左右节点一样不,判断都有没有左右子树和判断左右子树的值一样不一样。

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);
    }
  1. unique-binary-search-trees

题目描述
给定一个值n,能构建出多少不同的值包含1…n的二叉搜索树(BST)?
例如
给定 n = 3, 有五种不同的二叉搜索树(BST)

首先知道二叉搜索树的概念,对于任一个节点,它的左子树都比他小,右子树都比他大。二叉树中序遍历结果是升序的就是二叉搜索树。

当n = 3 时,有五种不同的二叉搜索树
在这里插入图片描述
根据二叉搜索树的概念,可以得到递归的思路,就是把每次的n规模的节点拆成左边i - 1个右边n - i个

public static int numTrees(int n) {
		if(n == 0 || n == 1) {
			return 1;
		}
		int sum = 0;
		for (int i = 1; i <= n; i++) {
			sum += numTrees(i - 1) * numTrees(n - i);
		}
		return sum;
	}
//在递归的过程中有重复性的解,所以可以改成动态规划
	public static int numTreeDp(int n) {
		int[] dp = new int[n + 1];
		dp[0] = dp[1] = 1;
		for (int i = 2 ;i <= n;i ++) {
			for (int j = 1; j <= i; j++) {
				dp[i] += dp[j-1] * dp[i-j];
			}
		}
		return dp[n];
	}
  1. populating-next-right-pointers-in-each-node

题目描述
给定一个二叉树
struct TreeLinkNode {
TreeLinkNode *left;
TreeLinkNode *right;
TreeLinkNode *next;
}
填充所有节点的next指针,指向它右兄弟节点。如果没有右兄弟节点,则应该将next指针设置为NULL。
初始时,所有的next指针都为NULL
注意:
你只能使用常量级的额外内存空间
可以假设给出的二叉树是一个完美的二叉树(即,所有叶子节点都位于同一层,而且每个父节点都有两个孩子节点)。

//递归解法
public static void connect(TreeLinkNode root) {
		if(root == null) {
			return ;
		}
		if(root.left != null && root.right != null) {
			root.left.next = root.right;
		}
		if(root.next != null && root.right != null) {
			root.right.next = root.next.left;
		}
		connect(root.left);
		connect(root.right);
	}
	
	//非递归
	public static void connect2(TreeLinkNode root) {
		if(root == null) {
			return;
		}
		TreeLinkNode p = root;
		TreeLinkNode q = null;
		while(p.left != null) {
			q = p;
			while(q != null) {
				q.left.next = q.right;
				if(q.next != null) {
					q.right.next = q.next.left;
				}
				q = q.next;
			}
			p = p.left;
		}
	}
  1. balanced-binary-tree

题目描述
判断给定的二叉树是否是平衡的
在这个问题中,定义平衡二叉树为每个节点的左右两个子树高度差的绝对值不超过1的二叉树

判读一颗二叉树是否是平衡二叉树。二叉树的每一个节点的左子树和右子树的高度差不超过1。面对二叉树中的高度套路化,可以利用递归,列出可能性,设计递归返回思路,返回信息类型(需要的信息柔和成一个类)。

public class Tree{
		private int val;
		private Tree left;
		private Tree right;
		
		public Tree(int val) {
			this.val = val;
		}
	}
	
	public static class Height{
		private int h;
		private boolean isB;
		
		public Height(int h,boolean isB) {
			this.h = h;
			this.isB = isB;
		}
	}
	
	public static Height process(Tree head) {
		
		if(head == null) {
			return new Height(0, true);
		}
		Height left = process(head.left);
		if(!left.isB) {
			return new Height(0, false); 
		}
		Height right = process(head.right);
		if(!right.isB) {
			return new Height(0, false);
		}
		
		if(Math.abs(left.h - right.h) > 1) {
			return new Height(0,false);
		}
		
		return new Height(Math.max(left.h, right.h) + 1, true);
	}
	
	public static boolean isB(Tree head) {
		return process(head).isB;
	}
  1. binary-tree-inorder-traversal

题目描述:
非递归中序遍历一颗二叉树

public ArrayList<Integer> inorderTraversal(TreeNode root) {
		ArrayList<Integer> arrayList = new ArrayList<Integer>();
		Stack<TreeNode> stack = new Stack<TreeNode>();
		while(!stack.isEmpty() || root != null) {
			if(root != null) {
				stack.push(root);
				root = root.left;
			}else {
				root = stack.pop();
				arrayList.add(root.val);
				root = root.right;
			}
		}
		return arrayList;
	}
  1. binary-tree-preorder-traversal

题目描述:
非递归先序遍历一颗二叉树

public ArrayList<Integer> preorderTraversal(TreeNode root) {
		ArrayList<Integer> arrayList = new ArrayList<Integer>();
		Stack<TreeNode> stack = new Stack<TreeNode>();
		if (root != null) {
			stack.add(root);
			while (!stack.isEmpty()) {
				root = stack.pop();
				arrayList.add(root.val);
				if (root.right != null) {
					stack.push(root.right);
				}
				if (root.left != null) {
					stack.push(root.left);
				}
			}
		}
		return arrayList;
	}
  1. path-sum

题目描述
给定一个二叉树和一个值sum,判断是否有从根节点到叶子节点的节点值之和等于sum的路径,
例如:
给出如下的二叉树,sum=22,

public boolean hasPathSum(TreeNode root, int sum) {
		return isTOrF(root, sum, 0);
	}

	//递归之前,先想清楚递归的条件再写。递归的basecase是写递归的关键
	private boolean isTOrF(TreeNode root, int sum, int res) {
		// TODO Auto-generated method stub
		if (root == null) {
			return false;
		}
		if(root.left == null && root.right == null && sum == res + root.val) {
			return true;
		}
		return isTOrF(root.left, sum, res + root.val) || isTOrF(root.right, sum, res + root.val);
	}
  1. binary-tree-level-order-traversal

题目描述
给定一个二叉树,返回该二叉树层序遍历的结果,(从左到右,一层一层地遍历)
例如:
给定的二叉树是{3,9,20,#,#,15,7},
该二叉树层序遍历的结果是
[↵ [3],↵ [9,20],↵ [15,7]↵]

public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
		ArrayList<ArrayList<Integer>> arrayLists = new ArrayList<ArrayList<Integer>>();
		if(root == null) {
			return arrayLists;
		}
		Queue<TreeNode> queue = new LinkedList<TreeNode>();
		queue.offer(root);
		
		//这个题的关键在于获得每层的节点个数
		while(!queue.isEmpty()) {
			int num = queue.size();//获得每层的节点个数
			ArrayList<Integer> arrayList = new ArrayList<Integer>();
			for (int i = 0; i < num; i++) {
				root = queue.peek();
				if(root.left != null) {
					queue.offer(root.left);
				}
				if(root.right != null) {
					queue.offer(root.right);
				}
				arrayList.add(queue.poll().val);
			}
			arrayLists.add(arrayList);
		}
		return arrayLists;
	}
  1. symmetric-tree

题目描述
给定一棵二叉树,判断琪是否是自身的镜像(即:是否对称)
递归给的这棵树,其中一个递归左边的,另一个递归右边的。

public boolean isSymmetric(TreeNode root) {
		return root(root,root);
	}
	
	public boolean root(TreeNode left,TreeNode right) {
		if(left == null && right == null) {
			return true;
		}
		if(left == null || right == null) {
			return false;
		}
		return left.val == right.val && root(left.left,right.right) && root(left.right,right.left);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值