研究生算法第二次作业第一题 算法实现 python版

def find_kth(X, x_start, x_len, Y, y_start, y_len, k):
    if x_len == 0:
        return Y[y_start + k - 1]
    if y_len == 0:
        return X[x_start + k - 1]
    if k == 1:
        return min(X[x_start], Y[y_start])
    i = min(k // 2, x_len)
    j = min(k // 2, y_len)
    if X[x_start + i - 1] < Y[y_start + j - 1]:
        return find_kth(X, x_start + i, x_len - i, Y, y_start, y_len, k - i)
    else:
        return find_kth(X, x_start, x_len, Y, y_start + j, y_len - j, k - j)

def find_median(X, Y):
    n = len(X)
    median1 = find_kth(X, 0, n, Y, 0, n, n)
    median2 = find_kth(X, 0, n, Y, 0, n, n + 1)
    return (median1 + median2) / 2

# 处理输入
n = int(input("请输入n(输入-1随机生成): "))
if n == -1:
    import random
    n = random.randint(1, 10)
    X = sorted(random.sample(range(1, 100), n))
    Y = sorted(random.sample(range(1, 100), n))
    print(f"随机生成n={n}:")
    print("X数组:", X)
    print("Y数组:", Y)
else:
    X = list(map(int, input("请输入X数组(已排序): ").split()))
    Y = list(map(int, input("请输入Y数组(已排序): ").split()))
    if len(X) != n or len(Y) != n:
        print("错误:数组长度不等于n")
        exit()

print("中位数为:", find_median(X, Y))

这段Python代码用于高效地查找两个已排序数组的中位数,时间复杂度为 O(logn)。以下是详细解释:

核心功能

  1. find_kth 函数
    采用分治策略在两个有序数组中查找第 k 小的元素:
    • 参数说明
      • XY:输入的两个有序数组。
      • x_starty_start:当前子数组的起始索引。
      • x_leny_len:当前子数组的长度。
      • k:目标元素的排名(第k小)。
    • 终止条件
      • 如果 X 的子数组为空(x_len == 0),直接返回 Y 的第 k 个元素。
      • 如果 Y 的子数组为空(y_len == 0),直接返回 X 的第 k 个元素。
      • 如果 k == 1,返回 X[x_start] 和 Y[y_start] 中的较小值。
    • 分治逻辑
      • 计算要比较的元素位置:i = min(k//2, x_len) 和 j = min(k//2, y_len)
      • 比较 X[x_start + i - 1] 和 Y[y_start + j - 1]
        • 如果 X 的元素更小,则排除 X 的前 i 个元素,递归查找剩余部分的第 k-i 小元素。
        • 否则排除 Y 的前 j 个元素,递归查找剩余部分的第 k-j 小元素。
  2. find_median 函数
    • 假设两个数组长度相同(均为 n)。
    • 合并后的中位数为第 n 和第 n+1 小元素的平均值。
    • 调用两次 find_kth 分别获取这两个元素的值。
  3. 输入处理
    • 用户可手动输入两个有序数组,或输入 -1 随机生成测试数据。
    • 随机生成时,会生成两个长度为 n(1到10之间)的有序数组,并打印结果。

示例说明

假设输入数组:

  • X = [1, 3, 5]
  • Y = [2, 4, 6]

执行流程

  1. find_median 调用 find_kth(n=3) 和 find_kth(n+1=4)
  2. find_kth(3) 通过分治排除得到第3小元素为3。
  3. find_kth(4) 通过分治排除得到第4小元素为4。
  4. 中位数为 (3+4)/2=3.5。

算法优势

  • 时间复杂度:每次递归排除约一半元素,复杂度为 O(logn)。
  • 空间复杂度:递归栈深度为 O(logn)。
  • 无需合并数组:避免了 O(n) 的额外空间开销。

注意事项

  • 输入数组需预先排序。
  • 代码假设两个数组长度相同,若处理不同长度数组需调整 find_median 的参数。
  • 随机生成的数据范围为1到99,可修改 random.sample(range(1, 100), n) 调整范围。

代码对比(与C++版本差异)

  1. 参数传递:Python通过起始索引(x_starty_start)和长度(x_leny_len)传递子数组,而C++通过指针偏移(如 X+i)直接操作数组。
  2. 随机生成逻辑:Python使用 random.sample 和 sorted 生成有序数组,C++通过循环和手动排序实现。
  3. 输入处理:Python通过 input().split() 读取数组,C++通过循环和 cin 读取。

这段代码是解决两个有序数组中位数问题的经典分治算法实现,高效且易于理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值