• 算法进修Day-38


    算法进修Day-38

    77. 组合

    难度:中等
    题目要求:
    给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。

    示例1

    输入:n = 4, k = 2
    输出:
    [
    [2,4],
    [3,4],
    [2,3],
    [1,2],
    [1,3],
    [1,4],
    ]

    示例2

    输入:n = 1, k = 1
    输出:[[1]]

    题解

    利用 D F S DFS DFS 算法可解
    n u m num num 表示当前遍历到的数字,初始时 n u m = 1 num=1 num=1。回溯过程中,以下两种情况可以直接返回。

    • 如果当前组合中有 k k k 个数,则得到一个 k k k 个数的组合,将其添加到答案中,不需要继续遍历更多的数字。

    • 如果当前组合中的数字过少,即使将 [ n u m , n ] [num,n] [num,n] 范围中的所有整数都加入当前组合都无法使组合中的数字个数达到 k k k,则在当前组合的情况下一定不可能得到 k k k 个数的组合。

    其余情况下,对于当前遍历到的数字 n u m num num,分别考虑将其加入组合与不加入组合两种情况,并执行回溯。

    使用剪枝的情况下,可以排除不可能的组合,需要遍历的组合数从 2 n 2^n 2n 减少到 C n k C_n^k Cnk

    想法代码

    class Solution
    {
        public static void Main(String[] args)
        {
            Solution solution = new Solution();
            int n = 4;
            int k = 2;
            IList> res = solution.Combine(n, k);
            foreach (var i in res)
            {
                foreach (var j in i)
                {
                    Console.Write(j + " ");
                }
                Console.WriteLine();
            }
        }
    
        public IList> Combine(int n, int k)
        {
            IList> res = new List>();
            List list = new List();
            if (n < k || k <= 0)
            {
                return(IList>)(list);
            }
    
            DFS(n, k, 1, list, res);
            return res;
        }
    
        public void DFS(int n, int k, int begin, IList list, IList> res)
        {
            IList path = new List();
            if (list.Count == k)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    path.Add(list[i]);
                }
                res.Add(path);
                return;
            }
    
            for (int i = begin; i <= n; i++)
            {
                list.Add(i);
                DFS(n,k,i+1,list,res);
                list.RemoveAt(list.Count-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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    78. 子集

    难度:中等
    题目要求
    给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

    解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

    示例1

    输入:nums = [1,2,3]
    输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

    示例2

    输入:nums = [0]
    输出:[[],[0]]

    题解

    利用回溯算法可解
    每个结果都需要存储,不需要约束条件
    由于每个都需要存储,所以不需要剪枝
    注意,这个算法依旧需要回头

    想法代码

    public class Solution
    {
        public static void Main(string[] args)
        {
            Solution solution = new Solution();
            int[] nums = { 1, 2, 3 };
            IList> res = solution.Subsets(nums);
            foreach (var i in res)
            {
                foreach (var j in i)
                {
                    Console.Write(j + " ");
                }
                Console.WriteLine();
            }
        }
        public IList> Subsets(int[] nums)
        {
            IList> ans = new List>();
            if (nums == null || nums.Length == 0)
            {
                return ans;
            }
    
            DFS(nums, new List(), 0, ans);
            return ans;
        }
    
        public void DFS(int[] nums, List path, int start,IList> ans)
        {
            ans.Add(new List(path));
    
            for (int i = start; i < nums.Length; i++)
            {
                path.Add(nums[i]);
    
                DFS(nums, path, i + 1,ans);
    
                path.Remove(nums[i]);
            }
        }
    }
    
    • 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
    • 41
    • 42
  • 相关阅读:
    ‘setuptools‘ is a dependency of conda and cannot be removed from
    Java集合学习详解(2023年史上最全版)
    wget命令
    一起刷算法与数据结构-树篇1
    微信小程序毕业设计-基于Java后端的微信小程序源码150套(附源码+数据库+演示视频+LW)
    ssm+vue基于微信小程序的捷邻生活便利购物超市商城系统#毕业设计
    day35 XSS跨站&反射&存储&DOM&盲打&劫持
    Qt TCP 分包粘包的解决方法
    C++STL——string类
    Git 使用技巧:5个提高效率的命令,不再只会pull和push
  • 原文地址:https://blog.csdn.net/Aubyn11/article/details/134044764