京东开奖,为了招人真的是下猛药了。。

科技   2024-11-07 10:10   上海  

精品推荐

《征服数据结构》专栏:50多种数据结构彻底征服

《经典图论算法》专栏:50多种经典图论算法全部掌握


最近京东也开奖了,为了招人真的是下猛药了,年薪高达70万,京东今年给的确实挺高。之前美团开奖的时候我以为美团给的已经很高的了,结果和京东一对比简直不值一提。









--------------下面是今天的算法题--------------


来看下今天的算法题,这题是LeetCode的第107题:二叉树的层序遍历 II。


问题描述



来源:LeetCode第107题
难度:中等

给你二叉树的根节点 root ,返回其节点值自底向上的层序遍历。(即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

示例1:

输入:root = [3,9,20,null,null,15,7]

输出:[[15,7],[9,20],[3]]

示例2:

输入:root = [1]

输出:[[1]]


  • 树中节点数目在范围 [0, 2000] 内

  • -1000 <= Node.val <= 1000


问题分析



这题是让返回二叉树节点值从下往上的层序遍历,对于二叉树的层序遍历我们前面讲过二叉树的层序遍历,之前讲的是从上往下的层序遍历,而这题是从下往上的层序遍历。

这是一道典型的二叉树BFS遍历,只需要把之前的代码稍微修改一下即可,这里就不在重复介绍。

我们来看另一种解法,使用DFS解决,可以参照二叉树的前序遍历,对二叉树的每一层都创建一个集合list,然后把每一层的节点存放到当前层所在的集合中,最后在进行反转即可,比如示例 1 中的集合[[3],[9,20],[15,7]]反转之后就变成了[[15,7],[9,20],[3]]。

下面代码中除了java语言使用的是直接插入的方式,最后不需要反转,其他的C++,Python在最后都进行了反转。

JAVA:
public List<List<Integer>> levelOrderBottom(TreeNode root) {
    List<List<Integer>> ans = new LinkedList<>();
    dfs(ans, root, 0);
    return ans;
}

public void dfs(List<List<Integer>> ans, TreeNode root, int level) {
    if (root == null)
        return;
    // 初始化下一层的集合
    if (level == ans.size())
        ans.add(0new ArrayList<>());
    // 这里就相当于从下往上打印了
    ans.get(ans.size() - level - 1).add(root.val);
    // 递归左右子树
    dfs(ans, root.left, level + 1);
    dfs(ans, root.right, level + 1);
}

C++:
public:
    vector<vector<int>> levelOrderBottom(TreeNode *root) {
        vector<vector<int>> ans;
        dfs(ans, root, 0);
        reverse(ans.begin(), ans.end());// 反转
        return ans;
    }

    void dfs(vector<vector<int>> &ans, TreeNode *root, int level) {
        if (root == nullptr)
            return;
        // 初始化下一层的集合
        if (level == ans.size()) {
            vector<int> tmp;
            ans.emplace_back(tmp);
        }
        // 把节点的值添加到对应的集合中
        ans[level].push_back(root->val);
        // 递归左右子树
        dfs(ans, root->left, level + 1);
        dfs(ans, root->right, level + 1);
    }
};

Python:
def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
    def dfs(tree: TreeNode, level: int):
        if tree is None:
            return
            # 初始化下一层的集合
        if level == len(ans):
            ans.append([])
            # 这里就相当于从后往前打印了
        ans[level].append(tree.val)
        # 递归左右子树
        dfs(tree.left, level + 1)
        dfs(tree.right, level + 1)

    ans = []
    dfs(root, 0)
    return ans[::-1]  # 结果反转


笔者简介
博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解800多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档


《征服数据结构》专栏

数组稀疏表(Sparse Table)单向链表双向链表块状链表跳表队列和循环队列双端队列单调队列单调栈双端栈散列表字典树(Trie树)ArrayMapSparseArray二叉树二叉搜索树(BST)笛卡尔树AVL树树堆(Treap)FHQ-Treap哈夫曼树滚动数组差分数组LRU缓存LFU缓存

……


《经典图论算法》专栏

图的介绍图的表示方式邻接矩阵转换广度优先搜索(BFS)深度优先搜索(DFS)A*搜索算法迭代深化深度优先搜索(IDDFS)IDA*算法双向广度优先搜索迪杰斯特拉算法(Dijkstra)贝尔曼-福特算法(Bellman-Ford)SPFA算法弗洛伊德算法(Floyd)卡恩(Kahn)算法基于DFS的拓扑排序约翰逊算法(Johnson)

……

数据结构和算法
王一博,《算法秘籍》作者,1000多页的pdf算法题我也已经整理完成,在公众号“数据结构和算法”中回复关键字“pdf”即可下载。
 最新文章