【科学刷题】归并 / 归并排序 的各种应用

1 归并问题

1.1 不用额外空间合并两个有序数组

合并两个有序数组AB,A预先开辟了足够容纳AB的空间,不能使用额外的空间

def merge(A, B, A_len):
    B_len = len(B)
    k = B_len + A_len - 1
    i = A_len - 1
    j = B_len - 1
    while i >= 0 and j >= 0:
        if A[i] > B[j]:
            A[k] = A[i]
            k -= 1
            i -= 1
        else:
            A[k] = B[j]
            k -= 1
            j -= 1
    while i >= 0:
        A[k] = A[i]
        k -= 1
        i -= 1
    while j >= 0:
        A[k] = B[j]
        k -= 1
        j -= 1


def test_case(A, B):
    A_len = len(A)
    new_A = A + [0] * len(B)
    merge(new_A, B.copy(), A_len)
    nums = A + B
    nums.sort()
    print(f'new_A: {new_A}, nums: {nums}')
    assert new_A == nums


test_case([1, 2, 3], [2, 4])
test_case([1, 3, 5], [2, 4])

1.2 链表的归并

剑指 Offer 25. 合并两个排序的链表

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        p1 = l1
        p2 = l2
        res = ListNode(0)
        p = res
        while p1 and p2:
            if p1.val < p2.val:
                cp = p1
                p1 = p1.next  # 写后面无效
            else:
                cp = p2
                p2 = p2.next
            p.next = cp
            p = p.next
        p.next = p1 if p1 else p2
        return res.next

2 归并排序

2.1 递归版本

void merge(vector<int> &nums, int l, int r, int mid) {
   
    int i = l, j = mid + 1, k = 0;
    vector<int> merged(r - l + 1, 0);
    while (i <= mid && j <= r) {
   
        if (nums[i] < nums[j]) merged[k++] = nums[i++];
        else merged[k++] = nums[j++];
    }
    while (i <= mid) merged[k++] = nums[i++];
    while (j <= r) merged[k++] = nums[j++];
    for (i = 0; i < k; ++i) nums[l + i] = merged[i];
}

void merge_sort(vector<int> &nums, int l, int r) {
   
    if (l >= r) return;
    int mid = (l + r) / 2;
    merge_sort(nums, l, mid);
    merge_sort(nums, mid + 1, r);
    merge(nums,
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值