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

不使用比较运算符在O(nlog(n))时间内对整数数组按值分组的算法问询

核心思路

利用二分查找匹配新元素的所属分组,将每个元素的query调用次数控制在O(logn)量级,总调用次数符合O(nlogn)要求。
核心判断逻辑:如果将新元素加入若干个已有分组的代表元素集合后,query返回的不同值数量没有增加,说明新元素的值已经存在于这些分组中。

具体实现步骤

  1. 按顺序逐个处理数组下标(不直接访问元素值,仅用下标指代元素),同时维护每个分组的代表元素列表(每个分组取第一个元素作为代表)
  2. 对于当前处理的新下标x,在已有的分组集合中做二分查找:
    • 取二分中点mid,将前mid+1个分组的代表元素和x组成查询子集
    • 若query(子集)等于mid+1(前mid+1个分组本身有mid+1个不同值),说明x的值存在于前mid+1个分组中,收缩右边界
    • 否则说明x的值不在前mid+1个分组中,收缩左边界
  3. 二分结束后验证左边界指向的分组是否和x值相等,相等就加入该分组,否则新建分组存储x

完整代码实现

import random

# 题目给定初始配置
n = 100
querycalls = 0
secretarray = [random.randint(0, n-1) for i in range(n)]

def query(items):
    global querycalls
    querycalls += 1
    return len(set(secretarray[i] for i in items))

groups = []
reps = [] # 存储每个分组的代表元素下标,不同代表对应值一定不同

# 核心算法实现
for x in range(n):
    if not groups:
        groups.append([x])
        reps.append(x)
        continue
    left = 0
    right = len(groups) - 1
    target = len(groups)
    # 二分查找所属分组
    while left <= right:
        mid = (left + right) // 2
        check_list = reps[:mid+1] + [x]
        distinct_cnt = query(check_list)
        if distinct_cnt == mid + 1:
            target = mid
            right = mid - 1
        else:
            left = mid + 1
    # 验证并加入分组
    if target < len(groups) and query([reps[target], x]) == 1:
        groups[target].append(x)
    else:
        groups.append([x])
        reps.append(x)

# 结果正确性验证
correct = True
# 验证同组元素值相同
for g in groups:
    base_val = secretarray[g[0]]
    for idx in g:
        if secretarray[idx] != base_val:
            correct = False
            break
    if not correct:
        break
# 验证不同组元素值不同
seen_vals = set()
for r in reps:
    if secretarray[r] in seen_vals:
        correct = False
        break
    seen_vals.add(secretarray[r])

print(f"分组正确性:{correct}")
print(f"总query调用次数:{querycalls}")
print(f"nlogn量级参考值(n=100时):{int(n*7)}")

复杂度说明

每个元素最多需要O(logk)次二分查询(k为当前已有的分组数,最大不超过n),加上1次验证查询,总query调用次数稳定在O(nlogn)量级。以n=100为例,调用次数通常在700~900之间,远低于O(n²)的10000次上限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:45:07