聊聊一个面试中经常出现的算法题:组合运算及其实际应用例子

简介: 聊聊一个面试中经常出现的算法题:组合运算及其实际应用例子

前言

组合运算是一个数据概念,具体来说,组合运算就是从给定元素集合中选择特定数量的元素进行运算,而不考虑元素的顺序,关注的是哪些元素被选中,而不关心它们的排列顺序。

比如,有一个整数数组 int[] numbers = { 1, 2, 3},它的所有组合就是:

1
2
3
1,2
1,3
2,3
1,2,3

简单例子:列出一个整数数组 int[] numbers = { 1, 2, 3, 4 } 的所有组合

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        int[] numbers = { 1, 2, 3, 4 };

        List<List<int>> combinations = GenerateCombinations(numbers);

        foreach (var combination in combinations)
        {
            Console.WriteLine(string.Join(", ", combination));
        }
    }

    static List<List<int>> GenerateCombinations(int[] numbers)
    {
        List<List<int>> result = new List<List<int>>();

        for (int i = 1; i <= numbers.Length; i++)
        {
            GenerateCombinationsUtil(numbers, i, 0, new List<int>(), result);
        }

        return result;
    }

    static void GenerateCombinationsUtil(int[] numbers, int k, int start, List<int> currentCombination, List<List<int>> result)
    {
        if (k == 0)
        {
            result.Add(new List<int>(currentCombination));
            return;
        }

        for (int i = start; i < numbers.Length; i++)
        {
            currentCombination.Add(numbers[i]);
            GenerateCombinationsUtil(numbers, k - 1, i + 1, currentCombination, result);
            currentCombination.RemoveAt(currentCombination.Count - 1);
        }
    }
}

运行后以上代码会生成整数数组 { 1, 2, 3, 4 } 的所有可能组合,并将这些组合打印到控制台。

进阶一:根据需要打印出数组的组合

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        int[] numbers = { 1, 2, 3, 4 };
        int k = 2; // 选择的元素数量

        List<List<int>> combinations = GenerateCombinations(numbers, k);

        foreach (var combination in combinations)
        {
            Console.WriteLine(string.Join(", ", combination));
        }
    }

    static List<List<int>> GenerateCombinations(int[] numbers, int k)
    {
        List<List<int>> result = new List<List<int>>();
        List<int> currentCombination = new List<int>();

        GenerateCombinationsHelper(numbers, k, 0, 0, currentCombination, result);

        return result;
    }

    static void GenerateCombinationsHelper(int[] numbers, int k, int start, int currentSize, List<int> currentCombination, List<List<int>> result)
    {
        if (currentSize == k)
        {
            result.Add(new List<int>(currentCombination));
            return;
        }

        for (int i = start; i < numbers.Length; i++)
        {
            currentCombination.Add(numbers[i]);
            GenerateCombinationsHelper(numbers, k, i + 1, currentSize + 1, currentCombination, result);
            currentCombination.RemoveAt(currentCombination.Count - 1);
        }
    }
}

进阶二:排列出集合的组合,所进行运算

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
    // 创建集合
        List<Item> itemsList = new List<Item>
    {
      new Item { Number = 1, Amount = 100 },
      new Item { Number = 2, Amount = 200 },
      new Item { Number = 3, Amount = 300 }
    };
    
    // 进行组合
    List<List<Item>> combinations = GenerateCombinations(itemsList);

    // 对组合结果进行运算
    StringBuilder sb = new StringBuilder(1024);
    foreach (var combination in combinations)
    {
      for (var i = 0; i < combination.Count; i++)
      {
        var item = combination[i];
        sb.Append(item.Number);
        if (i < combination.Count - 1)
        {
          sb.Append(" + ");
        }
      }
      var cash = combination.Sum(x => x.Amount);
      sb.AppendLine($" = {cash}");
    }
    
    // 打印结果
    Console.WriteLine(sb.ToString());
    }

    static List<List<Item>> GenerateCombinations(List<Item> numbers)
  {
    List<List<Item>> result = new List<List<Item>>();

    // 从 2 个元素开始进行组合
    for (int i=2; i <= numbers.Count; i++)
    {
      GenerateCombinationsHelper(numbers, i, 0, new List<Item>(), result);
    }

    return result;
  }

    static GenerateCombinationsHelper(List<Item> numbers, int k, int start, List<Item> currentCombination, List<List<Item>> result)
  {
    if (k == 0)
    {
      result.Add(new List<Item>(currentCombination));
      return;
    }

    for (int i = start; i < numbers.Count; i++)
    {
      currentCombination.Add(numbers[i]);
      GenerateCombinationsHelper(numbers, k - 1, i + 1, currentCombination, result);
      currentCombination.RemoveAt(currentCombination.Count - 1);
    }
  }
}

// 定义集合元素类
class Item
{
  // 编号
    public int Number { get; set; }
  
  // 金额
    public decimal Amount { get; set; }
}

总结

组合运算是面试中经常被问到的一个算法题,在实际业务中也会经常使用,希望以上例子对你有所帮助。

我是老杨,一个奋斗在一线的资深研发老鸟,让我们一起聊聊技术,聊聊人生。

都看到这了,求个点赞、关注、在看三连呗,感谢支持。


相关文章
|
22天前
|
JavaScript
【Vue面试题十四】、说说你对vue的mixin的理解,有什么应用场景?
这篇文章详细介绍了Vue中`mixin`的概念、应用场景和源码分析,解释了`mixin`如何用于代码复用、功能模块化,并通过实际代码示例展示了在Vue组件中局部混入和全局混入的使用方式。
【Vue面试题十四】、说说你对vue的mixin的理解,有什么应用场景?
|
22天前
|
Java
【Java基础面试十一】、int和Integer有什么区别,二者在做==运算时会得到什么结果?
这篇文章解释了Java中`int`基本数据类型和其包装类`Integer`之间的区别,并指出在进行`==`运算时,`Integer`会拆箱为`int`类型,然后比较它们的值是否相等。
【Java基础面试十一】、int和Integer有什么区别,二者在做==运算时会得到什么结果?
|
10天前
|
机器学习/深度学习 算法 数据挖掘
R语言中的支持向量机(SVM)与K最近邻(KNN)算法实现与应用
【9月更文挑战第2天】无论是支持向量机还是K最近邻算法,都是机器学习中非常重要的分类算法。它们在R语言中的实现相对简单,但各有其优缺点和适用场景。在实际应用中,应根据数据的特性、任务的需求以及计算资源的限制来选择合适的算法。通过不断地实践和探索,我们可以更好地掌握这些算法并应用到实际的数据分析和机器学习任务中。
|
14天前
|
算法 C++
A : DS串应用–KMP算法
这篇文章提供了KMP算法的C++实现,包括计算模式串的next数组和在主串中查找模式串位置的函数,用于演示KMP算法的基本应用。
|
17天前
|
缓存 算法 前端开发
深入理解缓存淘汰策略:LRU和LFU算法的解析与应用
【8月更文挑战第25天】在计算机科学领域,高效管理资源对于提升系统性能至关重要。内存缓存作为一种加速数据读取的有效方法,其管理策略直接影响整体性能。本文重点介绍两种常用的缓存淘汰算法:LRU(最近最少使用)和LFU(最不经常使用)。LRU算法依据数据最近是否被访问来进行淘汰决策;而LFU算法则根据数据的访问频率做出判断。这两种算法各有特点,适用于不同的应用场景。通过深入分析这两种算法的原理、实现方式及适用场景,本文旨在帮助开发者更好地理解缓存管理机制,从而在实际应用中作出更合理的选择,有效提升系统性能和用户体验。
41 1
|
24天前
|
机器学习/深度学习 自然语言处理 负载均衡
揭秘混合专家(MoE)模型的神秘面纱:算法、系统和应用三大视角全面解析,带你领略深度学习领域的前沿技术!
【8月更文挑战第19天】在深度学习领域,混合专家(Mixture of Experts, MoE)模型通过整合多个小型专家网络的输出以实现高性能。从算法视角,MoE利用门控网络分配输入至专家网络,并通过组合机制集成输出。系统视角下,MoE需考虑并行化、通信开销及负载均衡等优化策略。在应用层面,MoE已成功应用于Google的BERT模型、Facebook的推荐系统及Microsoft的语音识别系统等多个场景。这是一种强有力的工具,能够解决复杂问题并提升效率。
39 2
|
22天前
|
JavaScript 算法 索引
【Vue面试题二十三】、你了解vue的diff算法吗?说说看
这篇文章深入分析了Vue中的diff算法,解释了其在新旧虚拟DOM节点比较中的工作机制,包括同层节点比较、循环向中间收拢的策略,并通过实例演示了diff算法的执行过程,同时提供了源码层面的解析,说明了当数据变化时,如何通过Watcher触发patch函数来更新DOM。
【Vue面试题二十三】、你了解vue的diff算法吗?说说看
|
22天前
|
JavaScript 前端开发
【Vue面试题二十一】、Vue中的过滤器了解吗?过滤器的应用场景有哪些?
这篇文章介绍了Vue中的过滤器,包括过滤器的定义、使用方式、串联使用以及在Vue 3中的废弃情况,并探讨了过滤器在文本格式化、单位转换等场景下的应用,同时分析了过滤器在Vue模板编译阶段的工作原理。
【Vue面试题二十一】、Vue中的过滤器了解吗?过滤器的应用场景有哪些?
|
22天前
|
JavaScript 程序员 数据安全/隐私保护
【Vue面试题二十】、你有写过自定义指令吗?自定义指令的应用场景有哪些?
这篇文章详细介绍了Vue中的自定义指令,包括指令系统的概念、如何实现自定义指令的全局和局部注册,以及自定义指令的钩子函数。文章还提供了几个自定义指令的应用场景示例,如表单防止重复提交、图片懒加载和一键复制功能,展示了自定义指令的灵活性和强大功能。
【Vue面试题二十】、你有写过自定义指令吗?自定义指令的应用场景有哪些?
|
2天前
|
机器学习/深度学习 算法 Python
群智能算法:深入解读人工水母算法:原理、实现与应用
近年来,受自然界生物行为启发的优化算法备受关注。人工水母算法(AJSA)模拟水母在海洋中寻找食物的行为,是一种新颖的优化技术。本文详细解读其原理及实现步骤,并提供代码示例,帮助读者理解这一算法。在多模态、非线性优化问题中,AJSA表现出色,具有广泛应用前景。