算法进修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

想法代码

Csharp 复制代码
class Solution
{
    public static void Main(String[] args)
    {
        Solution solution = new Solution();
        int n = 4;
        int k = 2;
        IList<IList<int>> res = solution.Combine(n, k);
        foreach (var i in res)
        {
            foreach (var j in i)
            {
                Console.Write(j + " ");
            }
            Console.WriteLine();
        }
    }

    public IList<IList<int>> Combine(int n, int k)
    {
        IList<IList<int>> res = new List<IList<int>>();
        List<int> list = new List<int>();
        if (n < k || k <= 0)
        {
            return(IList<IList<int>>)(list);
        }

        DFS(n, k, 1, list, res);
        return res;
    }

    public void DFS(int n, int k, int begin, IList<int> list, IList<IList<int>> res)
    {
        IList<int> path = new List<int>();
        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);
        }
    }
}

78. 子集

难度:中等

题目要求

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

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

示例1

输入:nums = 1,2,3

输出:\[,1,2,1,2,3,1,3,2,3,1,2,3]

示例2

输入:nums = 0

输出:\[,0]

题解

利用回溯算法可解

每个结果都需要存储,不需要约束条件

由于每个都需要存储,所以不需要剪枝

注意,这个算法依旧需要回头

想法代码

Csharp 复制代码
public class Solution
{
    public static void Main(string[] args)
    {
        Solution solution = new Solution();
        int[] nums = { 1, 2, 3 };
        IList<IList<int>> res = solution.Subsets(nums);
        foreach (var i in res)
        {
            foreach (var j in i)
            {
                Console.Write(j + " ");
            }
            Console.WriteLine();
        }
    }
    public IList<IList<int>> Subsets(int[] nums)
    {
        IList<IList<int>> ans = new List<IList<int>>();
        if (nums == null || nums.Length == 0)
        {
            return ans;
        }

        DFS(nums, new List<int>(), 0, ans);
        return ans;
    }

    public void DFS(int[] nums, List<int> path, int start,IList<IList<int>> ans)
    {
        ans.Add(new List<int>(path));

        for (int i = start; i < nums.Length; i++)
        {
            path.Add(nums[i]);

            DFS(nums, path, i + 1,ans);

            path.Remove(nums[i]);
        }
    }
}
相关推荐
apcipot_rain10 分钟前
计科八股20260616(1)——堆存中位数、链表判环、黑白测试、敏捷开发与瀑布模型、配置管理、持续集成、池化
数据结构·算法·软件工程
JAVA面经实录9177 小时前
Java 数据结构与算法 (终极完整学习文档)
java·数据结构·算法
开源Z8 小时前
LeetCode 42 · 接雨水:从暴力到双指针的三步优化
算法·leetcode
旖-旎8 小时前
《LeetCode 695 岛屿的最大面积 FloodFill DFS 解法》
c++·算法·力扣·深度优先遍历·floodfill
syagain_zsx9 小时前
STL 之 vector 讲练结合
c++·算法
MartinYeung510 小时前
[论文学习]DP2Unlearning:高效且具保证的大型语言模型遗忘框架(基于差分隐私的 LLM Unlearning 方法)
学习·算法·语言模型
Tian_Hang11 小时前
C++原型模式(Protype)
开发语言·c++·算法
bIo7lyA8v11 小时前
算法复杂度的渐进分析与实际运行时间的差异的技术8
算法
yuan1999711 小时前
欧拉梁静力与屈曲计算的 MATLAB 实现(有限差分法 + 解析解)
开发语言·算法·matlab