首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查找使i<j和A[i] >= 2 A[j]的对数(i,j)

查找使i<j和A[i] >= 2 A[j]的对数(i,j)
EN

Stack Overflow用户
提问于 2021-03-28 15:27:09
回答 1查看 1.8K关注 0票数 1

问题是找到一个算法(最好使用分而治之的方法)来计算i= 2*Aj数组中所有有序对(i,j)的数目。

我已经知道一个O(2)方式,但我想要一个更有效的算法或日志顺序。

这是我在python中的代码:

代码语言:javascript
复制
ans = 0

def recursion(arr):
    global ans
    if len(arr) > 1:
        left = arr[:len(arr)//2]
        right = arr[len(arr)//2:]
        recursion(left)
        recursion(right)
        for i in left:
            for j in right:
                if i >= 2*j:
                    ans += 1

a = list(map(int, input().split()))
recursion(a)
print(ans)

样本输入: 8,1,9 ,4,1

预期产出:6

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-28 17:57:09

通过对每个数组的一半排序和调整合并/倒排计数的逻辑,可以使代码的征服部分更有效地工作。下面的Python代码利用Timsort生成一个线性时间排序的合并。

顺便说一句,我在给定的输入中计算了6个这样的对:(8, 1), (8, 4), (8, 1), (9, 4), (9, 1), (4, 1)

代码语言:javascript
复制
def merge(left, right):
    return sorted(left + right)


def recursion(arr):
    if len(arr) <= 1:
        return 0, arr
    half = len(arr) // 2
    left_ans, left = recursion(arr[:half])
    right_ans, right = recursion(arr[half:])
    cross_ans = 0
    j = 0
    for i in range(len(left)):
        while j < len(right) and left[i] >= 2 * right[j]:
            j += 1
        cross_ans += j
    return left_ans + cross_ans + right_ans, merge(left, right)


print(recursion([8, 1, 9, 4, 1])[0])
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66843058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档