leetcode深度优先搜索学习1
之前在学习树的深度优先遍历和广度优先遍历时就没学好。最近在找实习,准备面试,发现自己这块确实非常薄弱。特意去leetcode上找了几个题做一遍,希望能有所收获。
100 相同的树
判断两棵树是不是相同的,利用深度遍历将每一个节点的值进行比较,再比较该节点的左右子节点的值。其中需要注意的是对节点是否为null的判断。
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q == null){
return true;
}
if(isOneNull(q,p) || isOneNull(p,q)){
return false;
}
if(p.val != q.val){
return false;
}
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
public boolean isOneNull(TreeNode p,TreeNode q){
return (p == null) && (q != null);
}
}
101 对称二叉树
这个题要判断树是不是对称的,其实也就是去比较树的左右节点是否相同。所以用了这样的想法,分两个方向进行遍历。一个方向是从它的左节点开始遍历;而一个则是从它的右节点开始遍历。比较两节点的值是否一致。如果是对称的二叉树,则遍历到的所有节点的值都是一致的。
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null){
return true;
}
return isSymmetric(root.left,root.right);
}
public boolean isSymmetric(TreeNode r1,TreeNode r2){
if((r1 == null && r2 != null) || (r2 == null && r1 != null)){
return false;
}
if(r1 == null && r2 == null){
return true;
}
if(r1.val != r2.val){
return false;
}
return isSymmetric(r1.left,r2.right) && isSymmetric(r1.right,r2.left);
}
}
104 树的最大深度
求树的最大深度。深度遍历,选出路径的最大值。比较简单的一个题。
class Solution {
public int maxDepth(TreeNode root) {
if(root == null){
return 0;
}
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return left > right ? (left + 1):(right + 1);
}
}
105. 从前序与中序遍历序列构造二叉树
根据一棵树的前序遍历与中序遍历构造二叉树。
相信如果只是简单的做题的话,大家都可以从前序和中序遍历中快速构造出树。但是写起代码来可能就会有一点困难。其实大家都知道思路,但是难就难在写代码的时候coding跟不上思路。还是多写多练吧。
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder.length == 0 || inorder.length != preorder.length){
return null;
}
TreeNode root = new TreeNode(preorder[0]);
buildTreeCore(root,preorder,0,preorder.length - 1,inorder,0,inorder.length - 1);
return root;
}
public void buildTreeCore(TreeNode root,int[] preorder,int beginPre,int endPre,
int[] inorder,int beginIn,int endIn){
if(beginPre >= endPre || beginPre >= preorder.length){
return;
}
int val = preorder[beginPre];
int index = beginIn;
while(inorder[index] != val){
index++;
}
int leftLength = index - beginIn;
if(leftLength > 0){
TreeNode left = new TreeNode(preorder[beginPre + 1]);
root.left = left;
buildTreeCore(left,preorder,beginPre + 1,beginPre + leftLength,
inorder,beginIn,index - 1);
}
if(endIn - beginIn - leftLength > 0){
TreeNode right = new TreeNode(preorder[beginPre + leftLength + 1]);
root.right = right;
buildTreeCore(right,preorder,beginPre + leftLength + 1,endPre,
inorder,index + 1,endIn);
}
}
}
108. 将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
讲实话,最开始看到这个题我有点懵。但好好看题目之后,我发现这个题其实比较简单。因为左右子树的高度差不能超过1。所以每次就得取数组区间的中间值作为根节点。这对奇数来说很有效,但是如果区间长度为偶数,那么就会导致答案不唯一。取中线左边的数和取中线右边的数,这就造成了两种不同的树,存在了多个答案。
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if(nums.length == 0){
return null;
}
int mid = nums.length / 2;
TreeNode root = new TreeNode(nums[mid]);
root .left = sortedArrayToBSTCore(nums,0,mid - 1);
root.right = sortedArrayToBSTCore(nums,mid + 1,nums.length - 1);
return root;
}
public TreeNode sortedArrayToBSTCore(int[] nums,int begin,int end){
if(begin > end){
return null;
}
int mid = begin + (end - begin) / 2;
TreeNode node = new TreeNode(nums[mid]);
node.left = sortedArrayToBSTCore(nums,begin,mid - 1);
node.right = sortedArrayToBSTCore(nums,mid + 1,end);
return node;
}
}
今天暂时就先做到这里吧。感觉现在涉及到的还局限在树的问题上,还没有做图的深度优先遍历,而且今天做的题都是比较简单的题,明天加大难度。加油呀!
如果各位有别的问题,欢迎各位留言,大家一起加油努力。