🚝1.验证二叉搜索树
题目解析设计一个递归函数 isValid(TreeNode node,Integer min,Integer max)来递归判断,函数表示考虑以 node
为根的子树,判断子树中所有节点的值是否都在 (min,max)
的范围内(注意是开区间)。如果 node
节点的值 val
不在 (min,max) 的范围内说明不满足条件直接返回,否则我们要继续递归调用检查它的左右子树是否满足,如果都满足才说明这是一棵二叉搜索树。
那么根据二叉搜索树的性质,在递归调用左子树时,我们需要把上界 max
改为 node.val,即调用 isValid(node.left, min, node.val)
,因为左子树里所有节点的值均小于它的根节点的值。同理递归调用右子树时,我们需要把下界 min
改为 node.val
,即调用 isValid(node.right,val,max)
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
return isValid(root,null,null);
}
public boolean isValid(TreeNode node,Integer min,Integer max){
if (node==null){return true;}
int val =node.val;
if(min!=null&&val<=min){return false;}
if(max!=null&&val>=max){return false;}
if(!isValid(node.left,min,val)){return false;}
if(!isValid(node.right,val,max)){return false;}
return true;
}
}
🚝2.对称二叉树
题目解析
对称二叉树定义树中任意两个对称节点 left 和 right ,一定有:left.val = right.val ,即此两对称节点值相等。
left.left.val = right.right.val :即 left 的 左子节点 和 right 的 右子节点 对称;
left.right.val = right.left.val :即 left 的 右子节点 和 right 的 左子节点 对称。
根据以上规律,从顶至底递归,判断每对节点是否对称,从而判断树是否为对称二叉树.
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null){return true;}
else return isSymmetricTwo(root.left,root.right);
}
public boolean isSymmetricTwo(TreeNode left,TreeNode right){//判断两个节点是否对称
if(left==null&&right==null){return true;}
if(left==null||right==null||left.val!=right.val){return false;}
return isSymmetricTwo(left.left,right.right)&&isSymmetricTwo(left.right,right.left);
}
}
🚝3.二叉树的层序遍历
题目解析与扩展
在二叉树上进行 DFS (深度优先)遍历和 BFS 遍历(广度优先)
void dfs(TreeNode root) {
if (root == null) {
return;
}
dfs(root.left);
dfs(root.right);
}
void bfs(TreeNode root) {
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll(); // Java 的 pop 写作 poll()
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
}
显而易见,层序遍历选用BFS再适合不过,但是层序遍历要求我们区分每一层,返回一个二维数组。而 BFS 的遍历结果是一个一维数组,无法区分每一层。所以在每一层遍历开始前,先记录队列中的结点数量 n(也就是这一层的结点数量,也是队列目前元素的个数),然后一口气处理完这一层的 n 个结点(一起poll出来)。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result=new ArrayList<List<Integer>>();
Queue<TreeNode> queue=new ArrayDeque();
if(root!=null){queue.add(root);}
while(!queue.isEmpty()){
int size = queue.size();
List<Integer> level=new ArrayList<Integer>();
for(int i=0;i<size;i++){//一次性处理队列内所有的节点(一层)
TreeNode node=queue.poll();//拿出队列中的节点
level.add(node.val);
if(node.left!=null){queue.add(node.left);}
if(node.right!=null){queue.add(node.right);}
}
result.add(level);//将一层节点的集合放入结果集内
}
return result;
}
}
🚝4.将有序数组转换为二叉搜索树
题目解析 首先题目所给的数组是排好序的,我们可以选择数组中间数字作为二叉搜索树的根节点,这样分给左右子树的数字个数相同或只相差 1,可以使得树保持平衡。
选择中间位置左边的数字作为根节点,则根节点的下标为(left+mid)/2,然后根节点的左子节点是在数组前半部分选出根节点,右子节点是 是在数组后半部分选出根节点,递归得到树。
代码
/**
* 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 ArrayToBST(nums,0,nums.length-1);
}
public TreeNode ArrayToBST(int[] nums,int left,int right){
if(left > right){return null;}
int mid=(left+right)/2;
TreeNode root=new TreeNode(nums[mid]);
root.left=ArrayToBST(nums,left,mid-1);
root.right=ArrayToBST(nums,mid+1,right);
return root;
}
}