二叉树
记录:不需要二刷,秒
java
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
traverse(root);
return res;
}
List<Integer> res = new LinkedList<>();
void traverse(TreeNode root){
if(root == null){
return;
}
traverse(root.left);
res.add(root.val);
traverse(root.right);
}
}
记录:不需要二刷,秒
java
class Solution {
public int maxDepth(TreeNode root) {
if(root == null){
return 0;
}
int maxLeft = maxDepth(root.left);
int maxRight = maxDepth(root.right);
return Math.max(maxLeft,maxRight)+1;
}
}
记录:不需要二刷,秒
java
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null){
return root;
}
TreeNode leftTree = invertTree(root.left);
TreeNode rightTree = invertTree(root.right);
root.left = rightTree;
root.right = leftTree;
return root;
}
}
思考:不要跳进递归。站在一个节点root上看,怎么判断它是否对称?左右节点是否相等。左右节点如果有个为空怎么办?判断是否都为空,都为空则true,否则false。然后递归这个root节点的左子树,右子树,判断是否对称
牢记分解问题的思想 --- 抽出一个节点单独看
记录:需要二刷
java
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null){
return true;
}
return _isSymmetric(root.left,root.right);
}
boolean _isSymmetric(TreeNode root1,TreeNode root2){
if(root1 == null || root2 == null){
return root1 == root2;
}
if(root1.val != root2.val){
return false;
}
return _isSymmetric(root1.left,root2.right) && _isSymmetric(root1.right,root2.left);
}
}
思考:在计算leftMax和rightMax时顺便计算一下二叉树的直径
记录:需要二刷
java
class Solution {
public int diameterOfBinaryTree(TreeNode root) {
maxDepth(root);
return res;
}
int res = 0;
int maxDepth(TreeNode root){
if(root == null){
return 0;
}
int leftMax = maxDepth(root.left);
int rightMax = maxDepth(root.right);
res = Math.max(leftMax+rightMax,res);
return Math.max(leftMax,rightMax)+1;
}
}
思路:用一个队列依次存入当前遍历到的节点root,然后再将这个节点拿出来存到这一层track里,再把下一层root存入队列里,这一层遍历完把这一层track存到res里
记录:需要二刷
java
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null){
return res;
}
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
int size = q.size();
List<Integer> track = new ArrayList<>();
for(int i = 0;i < size;i++){
TreeNode cur = q.poll();
track.add(cur.val);
if(cur.left != null){
q.offer(cur.left);
}
if(cur.right != null){
q.offer(cur.right);
}
}
res.add(track);
}
return res;
}
}
思考:BST的核心就是中序遍历就是升序数组,这样每次把数组最中间的元素作为root,再分解构造即可
记录:需要二刷
java
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if(nums.length == 0){
return null;
}
return buildBST(nums,0,nums.length-1);
}
TreeNode buildBST(int[] nums,int start,int end){
if(start > end){
return null;
}
int middle = (start + end) / 2;
TreeNode root = new TreeNode(nums[middle]);
root.left = buildBST(nums,start,middle-1);
root.right = buildBST(nums,middle+1,end);
return root;
}
}
思考:构造一个验证函数,每次限制上下限,递归判断
记录:需要二刷
java
class Solution {
public boolean isValidBST(TreeNode root) {
return _isValidBST(root,null,null);
}
boolean _isValidBST(TreeNode root,TreeNode min,TreeNode max){
if(root == null){
return true;
}
if(min != null && min.val >= root.val){
return false;
}
if(max != null && max.val <= root.val){
return false;
}
return _isValidBST(root.left,min,root) && _isValidBST(root.right,root,max);
}
}
思考:直接遍历这个搜索树,中序遍历就是顺序数组,然后拿这个数组的第k个元素就行,则用rank变量记录
记录:不需要二刷
java
class Solution {
public int kthSmallest(TreeNode root, int k) {
traverse(root,k);
return res;
}
int res = 0;
int rank = 0;
void traverse(TreeNode root,int k){
if(root == null){
return;
}
traverse(root.left,k);
rank++;
if(rank == k){
res = root.val;
}
traverse(root.right,k);
}
}
思考:思路很简单就是层序遍历,每次拿最这一层最右边的树到结果。注意的是,层序遍历时先加root.right再加root.left,这样每次peek时是最右侧元素
记录:需要二刷
java
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null){
return res;
}
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
int size = q.size();
TreeNode last = q.peek();
for(int i = 0;i < size;i++){
TreeNode cur = q.poll();
if(cur.right != null){
q.offer(cur.right);
}
if(cur.left != null){
q.offer(cur.left);
}
}
res.add(last.val);
}
return res;
}
}