力扣hot100做题整理(41-50)
文章目录
- 1.二叉树得层序遍历
- 2.将有序数组转换为二叉搜索树
- 3.验证二叉搜索树(*)
- 4.二叉搜索树第k小的元素(*)
- 5.二叉树的右视图
- 6.二叉树展开为链表(*)
- 7.从前序与中序遍历序列构造二叉树(*)
- 8.路径总和Ⅲ(**)
- 9.二叉树的最近公共祖先(***)
- 10.二叉树中的最大路径和(**)
1.二叉树得层序遍历
使用队列实现层序遍历
Queue queue = new LinkedList<>(); //定义队列
queue.offer() // 入队
queue.poll() //出队
注意题目一开始得判空
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.offer(root);while (!queue.isEmpty()) {List<Integer> cur = new ArrayList<>();int len = queue.size();for (int i = 0; i < len; i++) {TreeNode node = queue.poll();cur.add(node.val);if (node.left != null) queue.offer(node.left);if (node.right != null) queue.offer(node.right);}res.add(cur);}return res;}
}
2.将有序数组转换为二叉搜索树
判空得条件为数组得长度为0
相信函数得定义
class Solution {public TreeNode sortedArrayToBST(int[] nums) {if (nums.length == 0) return null;int middle = nums.length/2;TreeNode root = new TreeNode(nums[middle]);root.left = sortedArrayToBST(Arrays.copyOfRange(nums, 0, middle));root.right = sortedArrayToBST(Arrays.copyOfRange(nums, middle+1, nums.length));return root;}
}
3.验证二叉搜索树(*)
中序遍历验证左右子树是否满足
注意pre定义为Long
class Solution {long pre = Long.MIN_VALUE;public boolean isValidBST(TreeNode root) {if (root == null) return true;boolean left = isValidBST(root.left);if(left == false) return false;if (pre >= root.val) return false;pre = root.val;boolean right = isValidBST(root.right);if (right == false) return false;return true;}
}
4.二叉搜索树第k小的元素(*)
中序遍历
结果用在全局变量里面,避免使用再递归里面
class Solution {int count = 0;int result = 0;public int kthSmallest(TreeNode root, int k) {dfs(root, k);return result;}public void dfs(TreeNode root, int k) {if (root == null) return;dfs(root.left, k);count++;if (count == k) result = root.val;dfs(root.right, k);return;}
}
5.二叉树的右视图
层序遍历
注意长度必须定义再循环的外面,因为queue的长度是动态变化的
class Solution {public List<Integer> rightSideView(TreeNode root) {List<Integer> res = new ArrayList<>();if (root == null) return res;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {int len = queue.size();for (int i = 0; i < len; i++) {TreeNode node = queue.poll();if (i == len-1) res.add(node.val);if (node.left != null) queue.offer(node.left);if (node.right != null) queue.offer(node.right);}}return res;}
}
6.二叉树展开为链表(*)
根节点的左子树右下角连接到根节点右子树
根节点右子树指向根节点左子树
根节点左子树设置为空
class Solution {public void flatten(TreeNode root) {if (root == null) return;TreeNode cur = root;while (cur != null) {if (cur.left != null) {TreeNode node = cur.left;while (node.right != null) node = node.right;node.right = cur.right;cur.right = cur.left;cur.left = null;}cur = cur.right;}}
}
7.从前序与中序遍历序列构造二叉树(*)
截取数组操作
int[] newNum = Arrays(nums, 0, index) 左闭右开获取新数组
class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {if (preorder.length == 0 || inorder.length == 0) return null;TreeNode root = new TreeNode(preorder[0]);// 找到中序遍历的下标,区分左右子树int index = 0;for (int i = 0; i < inorder.length; i++) {if (inorder[i] == root.val) {index = i;break;}}// 递归构造左子树int[] leftPreorder = Arrays.copyOfRange(preorder, 1, index+1);int[] leftInorder = Arrays.copyOfRange(inorder, 0, index);root.left = buildTree(leftPreorder, leftInorder);// 递归构造右子树int[] rightPreorder = Arrays.copyOfRange(preorder, index+1, preorder.length);int[] rightInorder = Arrays.copyOfRange(inorder, index+1, inorder.length);root.right = buildTree(rightPreorder, rightInorder);return root;}
}
8.路径总和Ⅲ(**)
计算某个节点为起始点满足的个数
BFS遍历每一个节点
注意curSum用long类型,否则会溢出
class Solution {public int pathSum(TreeNode root, int targetSum) {if (root == null) return 0;int res = 0;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {TreeNode node = queue.poll();res += dfs(node, 0L, targetSum);if (node.left != null) queue.offer(node.left);if (node.right != null) queue.offer(node.right);}return res;}// 计算当前节点为起始的满足条件的元素个数public int dfs(TreeNode root, long curNum, int targetSum) {if (root == null) return 0;int count = 0;curNum += root.val;if (curNum == targetSum) count++;count += dfs(root.left, curNum, targetSum);count += dfs(root.right, curNum, targetSum);return count;}
}
9.二叉树的最近公共祖先(***)
分类讨论
class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if (root == null || root == p || root == q) {return root;}TreeNode left = lowestCommonAncestor(root.left, p, q);TreeNode right = lowestCommonAncestor(root.right, p, q);if (left != null && right != null) return root;if (left == null && right != null) return right;if (left != null && right == null) return left;return null;}
}
10.二叉树中的最大路径和(**)
定义一个最大值
不断更新每个节点的最大路径和
返回给上一层某一边的最大路径和
class Solution {int res = Integer.MIN_VALUE;public int maxPathSum(TreeNode root) {dfs(root);return res;}public int dfs(TreeNode root) {if (root == null) return 0;int left = Math.max(0, dfs(root.left));int right = Math.max(0, dfs(root.right));res = Math.max(res, left + right + root.val); // 当前节点最大路径和return Math.max(left, right) + root.val; // 返回上一层的最大路径和(一边)}
}