You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何快速生成包含唯一随机整数的Stack?

优化随机唯一整数Stack生成的方案

你的代码核心问题在于每次用stack.Contains(h)做重复检查——Stack的Contains是线性遍历查找(时间复杂度O(n)),当需要的随机数数量count接近可选范围(upper - lower + 1)时,会频繁生成重复值,导致循环次数爆炸,速度骤降。下面给你两种针对性的优化方案:

方案一:用HashSet辅助查重(适合count远小于可选范围的场景)

用HashSet来记录已生成的随机数,它的Contains操作是O(1)的哈希查找,比Stack的线性查找快得多。代码示例:

public static Stack<int> RandomNumbersGenerator(int lower, int upper, int count)
{
    // 先做边界检查,避免无效输入
    if (lower > upper)
        throw new ArgumentException("lower不能大于upper");
    int totalAvailable = upper - lower + 1;
    if (count < 0 || count > totalAvailable)
        throw new ArgumentException("count超出有效范围");
    
    Stack<int> stack = new Stack<int>();
    HashSet<int> usedNumbers = new HashSet<int>();
    Random rnd = new Random();
    
    while (count > 0)
    {
        int num = rnd.Next(lower, upper + 1);
        if (usedNumbers.Add(num)) // Add返回false表示已存在,true则是新数
        {
            stack.Push(num);
            count--;
        }
    }
    return stack;
}

HashSet的Add方法本身就会判断是否存在,返回布尔值,这样可以避免先Contains再Add的两次操作,进一步提升效率。

方案二:洗牌法(适合count接近可选范围的场景)

当需要的随机数数量接近可选范围的总数时,反复生成随机数试错的效率极低,这时候直接生成所有可选数的列表,打乱顺序后取前count个,再转成Stack:

public static Stack<int> RandomNumbersGenerator(int lower, int upper, int count)
{
    // 边界检查
    if (lower > upper)
        throw new ArgumentException("lower不能大于upper");
    int totalAvailable = upper - lower + 1;
    if (count < 0 || count > totalAvailable)
        throw new ArgumentException("count超出有效范围");
    
    // 生成所有可选数的列表
    List<int> numbers = Enumerable.Range(lower, totalAvailable).ToList();
    Random rnd = new Random();
    
    // Fisher-Yates洗牌算法,原地打乱列表,时间复杂度O(m)
    for (int i = numbers.Count - 1; i > 0; i--)
    {
        int j = rnd.Next(i + 1);
        (numbers[i], numbers[j]) = (numbers[j], numbers[i]);
    }
    
    // 取前count个元素转成Stack
    return new Stack<int>(numbers.Take(count));
}

Fisher-Yates洗牌是高效的原地打乱算法,比用OrderBy(_ => rnd.Next())的方式更优(后者会额外创建大量中间对象,效率更低)。

选择建议

  • 如果count远小于可选范围(比如count ≤ 总数量的1/10),用方案一,内存占用更小;
  • 如果count接近总数量(比如count ≥ 总数量的1/2),用方案二,避免大量无效的随机数生成;
  • 可以在方法里加判断逻辑,自动切换两种方案,让方法适配所有场景。

内容的提问来源于stack exchange,提问作者MoonMan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 11:05:42