二叉搜索树的范围和 DFS深度优先搜索 1.递归 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Solution { int ans; public int rangeSumBST (TreeNode root, int low, int high) { ans = 0 ; dfs(root,low,high); return ans; } public void dfs (TreeNode node,int L,int R) { if (node!=null ){ if (L<=node.val&&node.val<=R){ ans+=node.val; } if (node.val>L){ dfs(node.left,L,R); } if (node.val<R){ dfs(node.right,L,R); } } } }
2.迭代 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Solution { public int rangeSumBST (TreeNode root, int low, int high) { int ans = 0 ; Stack<TreeNode> stack = new Stack<TreeNode>(); stack.push(root); while (!stack.isEmpty()){ TreeNode node = stack.pop(); if (node!=null ){ if (node.val>=low&&node.val<=high){ ans+=node.val; } if (node.val>low){ stack.push(node.left); } if (node.val<high){ stack.push(node.right); } } } return ans; } }
二叉树的最大深度 DFS 1 2 3 4 5 6 7 8 9 10 11 class Solution { public int maxDepth (TreeNode root) { if (root==null ){ return 0 ; }else { int maxLeftHight = maxDepth(root.left); int maxRightHighgt = maxDepth(root.right); return Math.max(maxLeftHight,maxRightHighgt)+1 ; } } }
面试题:汉诺塔 1 2 3 4 5 6 7 8 在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制: (1) 每次只能移动一个盘子; (2) 盘子只能从柱子顶端滑出移到下一根柱子; (3) 盘子只能叠在比它大的盘子上。 请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。 你需要原地修改栈。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public void hanota (List<Integer> A, List<Integer> B, List<Integer> C) { int n = A.size(); moveable(n,A,B,C); } public void moveable (int num,List<Integer>A,List<Integer> B,List<Integer> C) { if (num == 1 ){ C.add(A.remove(A.size()-1 )); return ; }else { moveable(num-1 ,A,C,B); C.add(A.remove(A.size()-1 )); moveable(num-1 ,B,A,C); } } }
递归顺序查找树 给你一个树,请你 按中序遍历 重新排列树,使树中最左边的结点现在是树的根,并且每个结点没有左子结点,只有一个右子结点。
示例 :
输入:[5,3,6,2,4,null,8,1,null,null,null,7,9]
方法一:中序遍历+构造新的树 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Solution { public TreeNode increasingBST (TreeNode root) { List<Integer> vals = new ArrayList<Integer>(); inorder(root,vals); TreeNode ans = new TreeNode(0 ); TreeNode cur = ans; for (int v : vals){ cur.right = new TreeNode(v); cur = cur.right; } return ans.right; } public void inorder (TreeNode node, List<Integer> vals) { if (node==null ) return ; inorder(node.left,vals); vals.add(node.val); inorder(node.right,vals); } }
方法二:中序递归遍历+更改树的连接关系 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution { TreeNode cur; public TreeNode increasingBST (TreeNode root) { TreeNode ans = new TreeNode(0 ); cur = ans; inorder(root); return ans.right; } public void inorder (TreeNode node) { if (node==null ) return ; inorder(node.left); node.left = null ; cur.right = node; cur = node; inorder(node.right); } }
面试题:biNode 二叉树数据结构TreeNode可用来表示单向链表(其中left置空,right为下一个链表节点)。实现一个方法,把二叉搜索树转换为单向链表,要求依然符合二叉搜索树的性质,转换操作应是原址的,也就是在原始的二叉搜索树上直接修改。
返回转换后的单向链表的头节点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution { TreeNode head = new TreeNode(-1 ); TreeNode prev = head; public TreeNode convertBiNode (TreeNode root) { makelist(root); return head.right; } public void makelist (TreeNode node) { if (node==null ){ return ; } makelist(node.left); prev.right = node; prev = node; node.left = null ; makelist(node.right); } }
这个图可以解释上面递归顺序查找树和biNode两道题中类似下面这样的代码
1 2 3 4 5 cur.right = node; cur = node; prev.right = node; prev = node;
第一条指令用于更新结点指向,后一天指令用于prev的指向,即指向下一个元素,方便下一次访问
面试题16.11 跳水板 你正在使用一堆木板建造跳水板。有两种类型的木板,其中长度较短的木板长度为shorter,长度较长的木板长度为longer。你必须正好使用k块木板。编写一个方法,生成跳水板所有可能的长度。
返回的长度需要从小到大排列。
二叉树的坡度 给定一个二叉树,计算 整个树 的坡度 。
一个树的 节点的坡度 定义即为,该节点左子树的节点之和和右子树节点之和的 差的绝对值 。如果没有左子树的话,左子树的节点之和为 0 ;没有右子树的话也是一样。空结点的坡度是 0 。
整个树的坡度就是其所有节点的坡度之和。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution { private int count; public int findTilt (TreeNode root) { calculate(root); return count; } public int calculate (TreeNode node) { if (node==null ){ return 0 ; } int left = calculate(node.left); int right = calculate(node.right); count+=Math.abs(left-right); return left+right+node.val; } }