这么逆天吗?华为od都卡27岁了。。。

科技   2024-10-21 10:10   上海  

精品推荐

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

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


一网友投递华为OD(外包),直接反馈年龄不合适,后来得知,北京的华为OD只要27岁以下的,并且OD里学历人均985。学历限制也就认了,毕竟人多,择优录取。年龄还要限制到27岁,有的硕士毕业都27岁了,如果中国所有企业都这样搞,大家也不用读研了,因为毕业连一天班都不用上就已经超过年龄限制了。



网友评论:





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


来看下今天的算法题,这题是LeetCode的第22题:括号生成。


问题描述



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

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。

示例1:

输入:n = 3

输出:["((()))","(()())","(())()","()(())","()()()"]

示例2:

输入:n = 1

输出:["()"]


  • 1 <= n <= 8


问题分析



这题让生成 n 对有效的括号,任何有效的括号都会满足下面两个条件:

1,有效括号中左括号的数量等于右括号的数量。

2,有效括号中任何位置左括号的数量都大于等于右括号的数量。


第一条很容易理解,我们来看第二条,比如有效括号"(())()",在任何一个位置右括号的数量都不大于左括号的数量,所以它是有效的。


如果像这样"())()",第3个位置是右括号,那么它前面只有一个左括号,而它和它前面的右括号有2个,所以无论如何都不能构成有效的括号。我们就以 n 等于 2 为例来画个图看一下。

选择的过程实际上就是一棵二叉树,左子树选择左括号,右子树选择右括号,选择的时候要剪掉一些不符合条件的分枝,到叶子节点的时候如果括号有效,就把它保存下来。


当左右括号的数量都选择完了就表示到叶子节点了,原理很清晰,我们来看下代码。

JAVA:
public List<String> generateParenthesis(int n) {
    List<String> ans = new ArrayList<>();
    dfs(ans, 00, n, "");
    return ans;
}

/**
 * @param ans    返回结果
 * @param left   左括号的使用数量
 * @param right  右括号的使用数量
 * @param n
 * @param curStr 当前节点的字符串
 */

private void dfs(List<String> ans, int left, int right, int n, String curStr) {
    if (left == n && right == n) {
        // 左右括号都使用完了,说明找到了有效的括号
        ans.add(curStr);
        return;
    }
    // 选择左括号,左右括号的数量都不能大于n
    if (left < n)
        dfs(ans, left + 1, right, n, curStr + "(");
    // 选择右括号,右括号数量不能大于左括号的数量。
    if (right < left)// 注意这里不能写等号,
        dfs(ans, left, right + 1, n, curStr + ")");
}

C++:
public:
    vector<stringgenerateParenthesis(int n) {
        vector<string> ans;
        dfs(ans, 00, n, "");
        return ans;
    }

    /**
     * @param ans    返回结果
     * @param left   左括号的使用数量
     * @param right  右括号的使用数量
     * @param n
     * @param curStr 当前节点的字符串
    */

    void dfs(vector<string> &ans, int left, int right, int n, string curStr) {
        if (left == n && right == n) {
            // 左右括号都使用完了,说明找到了有效的括号
            ans.push_back(curStr);
            return;
        }
        // 选择左括号,左右括号的数量都不能大于n
        if (left < n)
            dfs(ans, left + 1, right, n, curStr + "(");
        // 选择右括号,右括号数量不能大于左括号的数量。
        if (right < left)// 注意这里不能写等号,
            dfs(ans, left, right + 1, n, curStr + ")");
    }

Python:
def generateParenthesis(self, n: int) -> List[str]:
    def dfs(curStr, left, right):
        if left == n and right == n:
            # 左右括号都使用完了,说明找到了有效的括号
            ans.append(curStr)
            return
        # 选择左括号,左右括号的数量都不能大于n
        if left < n:
            dfs(curStr + "(", left + 1, right)
        # 选择右括号,右括号数量不能大于左括号的数量。
        if right < left:  # 注意这里不能写等号,
            dfs(curStr + ")", left, right + 1)

    ans = []
    dfs(""00)
    return ans


笔者简介
博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球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”即可下载。
 最新文章