持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
声明:本博客记录的题目全部来自于力扣,对这些题目进行整理的人为花花酱以及他的个人网站,本博客主要用来记录自己的算法学习的笔记。
二叉树的垂序遍历
本题来自于力扣987. 二叉树的垂序遍历 根据题目意思,我们可以先整个遍历这个树,并且对这个树进行标记(col, row, val),并使用这个三个值进行排序,col为第一排序,row为第二排序,val为第三排序。 使用dfs进行遍历,并标记,使用map存储标记 本题的题解主要参考宫水三叶的题解,点击连接有更多题解思路提供 题解
class Solution {
public List<List<Integer>> verticalTraversal(TreeNode root) {
Map<TreeNode,int []> map = new HashMap();
List<List<Integer>> result = new ArrayList();
map.put(root, new int[]{0,0,root.val});
recursion(root, map);
List<int[]> list = new ArrayList<>(map.values());
Collections.sort(list, (a, b)->{
if (a[0] != b[0]) return a[0] - b[0];
if (a[1] != b[1]) return a[1] - b[1];
return a[2] - b[2];
});
int n = list.size();
for (int i = 0; i < n; ) {
int j = i;
List<Integer> tmp = new ArrayList<>();
while (j < n && list.get(j)[0] == list.get(i)[0]){
tmp.add(list.get(j++)[2]);
}
result.add(tmp);
i = j;
}
return result;
}
public void recursion(TreeNode root, Map<TreeNode, int[]> map){
if(root == null){
return ;
}
int[] info = map.get(root);
int row = info[1], col = info[0], val = info[2];
if(root.left != null){
map.put(root.left, new int[]{col - 1, row + 1, root.left.val});
recursion(root.left, map);
}
if(root.right != null){
map.put(root.right, new int[]{col + 1, row + 1, root.right.val});
recursion(root.right, map);
}
}
}
使用dfs遍历的原理基本上和基础遍历差不多,这里主要学习到的是哈希表的灵活应用 以及接下来记录的排序使用
Collections.sort(list, (a, b)->{
if (a[0] != b[0]) return a[0] - b[0];
if (a[1] != b[1]) return a[1] - b[1];
return a[2] - b[2];
});
这个代码里面构造的是一个比较器: 如果第一个值减去第二个值,则是降序排序 如果第二值减去第一个值,则是升序排序 靠前的就是第一排序,第二排序,和第三排序
层数最深叶子节点的和
本题来自于力扣1302. 层数最深叶子节点的和 根据上述题目的学习,我们很快就能根据上面的风格写出如下代码
class Solution {
public int deepestLeavesSum(TreeNode root) {
Map<TreeNode, int[]> map = new HashMap();
map.put(root, new int[]{0,root.val});//row和val
dfs(root,map);
List<int[]> list = new ArrayList<>(map.values());
Collections.sort(list, (a, b)->{
if (a[0] != b[0]) return b[0] - a[0];
return b[1] - a[1];
});
int maxRow = list.get(0)[0];
int ans = 0;
int i = 0;
while(list.get(i)[0] == maxRow){
ans = ans + list.get(i)[1];
i++;
}
return ans;
}
public void dfs(TreeNode root, Map<TreeNode, int[]> map){
if(root == null){
return;
}
int[] info = map.get(root);
int row = info[0], val = info[1];
if(root.left != null){
map.put(root.left, new int[]{row + 1, root.left.val});
dfs(root.left, map);
}
if(root.right != null){
map.put(root.right, new int[]{row + 1, root.right.val});
dfs(root.right, map);
}
}
}
显然这个代码很长,而且执行效率很低,这个时候我们可以思考是否可以在遍历的时候就把最深的节点找出并得出结果呢?
改变思路就有了以下代码,很多事情同时做,同时比较
class Solution {
int deepRow;
int deepRowSum;
public int deepestLeavesSum(TreeNode root) {
dfs(root,0);
return deepRowSum;
}
public void dfs(TreeNode root, int row){
if(root == null){
return;
}
if(row > deepRow){
deepRow = row;
deepRowSum = 0;
}
if(row == deepRow){
deepRowSum = deepRowSum + root.val;
}
dfs(root.left, row + 1);
dfs(root.right, row + 1);
}
}