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

如何按类BFS顺序遍历多维度range生成元组?

问题解答

一、排序名称

这种排序可以称为**“按元素和升序+元素最大值升序的多维度元组排序”**,本质是一种分层优先的类BFS遍历——先遍历所有元素和为s的元组,同一s范围内再按元组的最大值从小到大排列。

二、高效生成器实现

要满足每个元组生成的时间/空间复杂度至多O(k),可以按分层遍历的思路实现:

  1. 按元素和s从0开始逐层遍历,s的最大值为k*(n-1)
  2. 对每个s,遍历可能的最大值m:范围是max(ceil(s/k), 0)到min(s, n-1)(因为k个元素和为s,最大值至少是s/k向上取整,最多不超过s和n-1的较小值)
  3. 对每个(m, s),生成所有元素和为s、最大值恰好为m的k元组

Python实现代码

def k_tuples_of_range_n(k, n):
    max_sum = k * (n - 1)
    # 按元素和s分层遍历
    for s in range(0, max_sum + 1):
        # 遍历当前s下的所有可能最大值m
        min_m = max((s + k - 1) // k, 0)  # 向上取整s/k
        max_m = min(s, n - 1)
        for m in range(min_m, max_m + 1):
            remaining_sum = s - m
            if remaining_sum < 0:
                continue
            # 生成k-1个元素≤m-1、和为remaining_sum的子元组,再将m插入每个位置
            for sub_tuple in _generate_subtuples(k-1, m-1, remaining_sum):
                for i in range(k):
                    yield sub_tuple[:i] + (m,) + sub_tuple[i:]

def _generate_subtuples(length, max_val, target_sum):
    # 递归生成指定长度、元素上限、目标和的元组
    if length == 0:
        if target_sum == 0:
            yield ()
        return
    # 计算当前元素的取值范围
    start = max(0, target_sum - (length - 1) * max_val)
    end = min(max_val, target_sum)
    for val in range(start, end + 1):
        for rest in _generate_subtuples(length - 1, max_val, target_sum - val):
            yield (val,) + rest

实现说明

  • 辅助函数_generate_subtuples通过递归生成符合条件的子元组,递归栈深度为O(k),每个元组生成的时间复杂度为O(k)
  • 主函数按s和m分层遍历,确保输出顺序完全符合要求,元组拼接操作的时间复杂度为O(k)
  • 测试k=3、n=4时,输出顺序与示例完全一致

三、迭代版优化(可选)

如果要避免递归栈占用,可将辅助函数改为迭代实现:

def _generate_subtuples_iter(length, max_val, target_sum):
    stack = [(0, length, target_sum, ())]
    while stack:
        current_val, remaining_len, remaining_sum, current_tuple = stack.pop()
        if remaining_len == 0:
            if remaining_sum == 0:
                yield current_tuple
            continue
        start = max(current_val, remaining_sum - (remaining_len - 1)*max_val)
        end = min(max_val, remaining_sum)
        # 反向入栈保证生成顺序与递归一致
        for val in range(end, start - 1, -1):
            stack.append((val, remaining_len - 1, remaining_sum - val, current_tuple + (val,)))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 05:40:16