HOT100–Day15–98. 驗證二叉搜索樹,230. 二叉搜索樹中第 K 小的元素,199. 二叉樹的右視圖
每日刷題系列。今天的題目是《力扣HOT100》題單。
題目類型:二叉樹。
關鍵:要深刻理解《遞歸》
98. 驗證二叉搜索樹
思路:
看到二叉搜索樹一定要想起“中序遍歷”
利用一個pre變量,記錄前驅節點。
中序遍歷一次,就相當于遍歷了一個單調數組。
class Solution {// 前驅節點private long pre = Long.MIN_VALUE;public boolean isValidBST(TreeNode root) {if (root == null) {return true;}// 左if (!isValidBST(root.left)) {return false;}// 中(本節點)// 如果違反單調性,向上返回falseif (root.val <= pre) {return false;}// 更新前驅節點pre = root.val;// 右if (!isValidBST(root.right)) {return false;}return true;}
}
230. 二叉搜索樹中第 K 小的元素
思路:
看到二叉搜索樹一定要想起“中序遍歷”。
中序遍歷,相當于用for遍歷了一個有序數組。返回數組中索引為k的元素。
class Solution {private int index = 0;private int k;private int target;public int kthSmallest(TreeNode root, int k) {this.k = k;midorder(root);return target;}// 中序遍歷,相當于用for遍歷了一個有序數組。返回數組中索引為k的元素。private void midorder(TreeNode node) {// 多寫一個index>=k,可以提前return,剪枝if (node == null || index >= k) {return;}if (node.left != null) {midorder(node.left);}// 中if (++index == k) {target = node.val;return;}if (node.right != null) {midorder(node.right);}}
}
199. 二叉樹的右視圖
思路:
先遞歸到右子樹,進入新depth的第一個節點就會是最右邊的
class Solution {List<Integer> res = new ArrayList<>();public List<Integer> rightSideView(TreeNode root) {dfs(root, 1);return res;}private void dfs(TreeNode node, int depth) {if (node == null) {return;}// 記錄進入這個深度的第一個節點if (depth > res.size()) {res.add(node.val);}// 先遞歸到右子樹,進入新depth的第一個節點就會是最右邊的dfs(node.right, depth + 1);dfs(node.left, depth + 1);}}
思路:
也可以用層序遍歷解決這道題。迭代法。
// 層序遍歷,每層的最后一個元素拿出來。
class Solution {public List<Integer> rightSideView(TreeNode root) {List<Integer> res = new ArrayList<>();if (root == null) {return res;}Deque<TreeNode> que = new ArrayDeque<>();que.offer(root);while (!que.isEmpty()) {int levelCount = que.size();for (int i = 0; i < levelCount; i++) {TreeNode node = que.pop();// 右子樹先入隊,就是把每層第一個元素拿出來if (node.right != null) {que.offer(node.right);}if (node.left != null) {que.offer(node.left);}// 當i是本層第一個節點的時候,把值加入到res里if (i == 0) {res.add(node.val);}}}return res;}
}