崩溃,你限你的,我卡我的。。。

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

精品推荐

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

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


据说明年有1200多万毕业生,就业压力也是相当大,为了提升毕业生就业率,教育部发文:严禁校招限定985,211。但我觉得解除限制也提升不了就业率,因为岗位是一定的,毕业人数是一定的,解除限制除了给普通院校学生更多的机会,对提升就业率好像没有什么帮助。


最近一位网友在面试的时候,HR就明确说了,985和211的放一坨,普通院校放一坨,如果985和211都签完了还不够,才会考虑普通院校,主打的就是你限你的,我卡我的,根本不把教育部的文件当回事。。。







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


来看下今天的算法题,这题是LeetCode的第216题:组合总和 III。


问题描述



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

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

1,只使用数字1到9

2,每个数字 最多使用一次 


返回所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。


示例1:

输入: k = 3, n = 7

输出: [[1,2,4]]

解释:

1 + 2 + 4 = 7

没有其他符合的组合了

示例2:

输入: k = 3, n = 9

输出: [[1,2,6], [1,3,5], [2,3,4]]

解释:

1 + 2 + 6 = 9

1 + 3 + 5 = 9

2 + 3 + 4 = 9

没有其他符合的组合了。


  • 2 <= k <= 9

  • 1 <= n <= 60


问题分析



这题是让从 1 到 9 之间选择 k 个数字,让这 k 个数字之和等于 n ,问有多少这种组合,这实际上是一道回溯算法题。

我们可以把它看作是一棵树,选择元素的过程可以把它看作树的一个分支,如果选择的元素个数大于 k 或者元素的和大于 n 就停止选择。

因为题中说的是组合,不是排列,也就是说[1,2,4]和[1,4,2]是一样的,所以选择当前元素之后下一步只能从他的下一个元素开始,比如示例 2 中的选择如下图所示:


JAVA:
public List<List<Integer>> combinationSum3(int k, int n) {
    List<List<Integer>> ans = new ArrayList<>();
    dfs(ans, new ArrayList<>(), k, n, 1);
    return ans;
}

private void dfs(List<List<Integer>> ans, List<Integer> path,
                 int k, int n, int start)
 
{
    if (path.size() >= k || n <= 0) {
        // 找到一组合适的
        if (path.size() == k && n == 0)
            ans.add(new ArrayList<>(path));
        return;
    }

    for (int i = start; i <= 9; i++) {
        path.add(i);// 选择当前值
        dfs(ans, path, k, n - i, i + 1);// 递归
        path.remove(path.size() - 1);// 撤销选择
    }
}

C++:
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        vector<vector<int>> ans;
        vector<int> path;
        dfs(ans, path, k, n, 1);
        return ans;
    }

    void dfs(vector<vector<int>> &ans, vector<int> &path,
             int k, int n, int start)
 
{
        if (path.size() >= k || n <= 0) {
            // 找到一组合适的
            if (path.size() == k && n == 0)
                ans.push_back(path);
            return;
        }

        for (int i = start; i <= 9; i++) {
            path.push_back(i);// 选择当前值
            dfs(ans, path, k, n - i, i + 1);// 递归
            path.pop_back();// 撤销选择
        }
    }

Python:
def combinationSum3(self, k: int, n: int) -> List[List[int]]:
    ans = []
    path = []

    def dfs(total: int, start: int):
        if len(path) >= k or total <= 0:
            # 找到一组合适的
            if len(path) == k and total == 0:
                ans.append(path[:])
            return
        for i in range(start, 10):
            path.append(i)  # 选择当前值
            dfs(total - i, i + 1)  # 递归
            path.pop()  # 撤销选择

    dfs(n, 1)
    return ans


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

《征服数据结构》专栏

《征服数据结构》数组

《征服数据结构》稀疏表(Sparse Table)

《征服数据结构》单向链表

《征服数据结构》双向链表

《征服数据结构》块状链表

《征服数据结构》跳表

《征服数据结构》队列和循环队列

《征服数据结构》双端队列

《征服数据结构》单调队列

《征服数据结构》栈

《征服数据结构》单调栈

《征服数据结构》双端栈

《征服数据结构》散列表

《征服数据结构》堆

《征服数据结构》字典树(Trie树)

《征服数据结构》ArrayMap

《征服数据结构》SparseArray

《征服数据结构》二叉树

《征服数据结构》二叉搜索树(BST)

《征服数据结构》笛卡尔树

《征服数据结构》AVL树

《征服数据结构》树堆(Treap)

《征服数据结构》FHQ-Treap

《征服数据结构》哈夫曼树

《征服数据结构》Splay 树

《征服数据结构》Splay 树(二)

《征服数据结构》滚动数组

《征服数据结构》差分数组

《征服数据结构》并查集(DSU)

《征服数据结构》LRU缓存

《征服数据结构》LFU缓存

……


《经典图论算法》专栏

《经典图论算法》图的介绍

《经典图论算法》图的表示方式

《经典图论算法》邻接矩阵转换

《经典图论算法》广度优先搜索(BFS)

《经典图论算法》深度优先搜索(DFS)

《经典图论算法》A*搜索算法

《经典图论算法》迭代深化深度优先搜索(IDDFS)

《经典图论算法》IDA*算法

《经典图论算法》双向广度优先搜索

《经典图论算法》迪杰斯特拉算法(Dijkstra)

《经典图论算法》贝尔曼-福特算法(Bellman-Ford)

《经典图论算法》SPFA算法

《经典图论算法》弗洛伊德算法(Floyd)

《经典图论算法》卡恩(Kahn)算法

《经典图论算法》基于DFS的拓扑排序

《经典图论算法》约翰逊算法(Johnson)

《经典图论算法》普里姆算法(Prim)

《经典图论算法》克鲁斯卡尔算法(Kruskal)

《经典图论算法》博鲁夫卡算法(Boruvka)

……


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