merge sorted array

merge sorted array

一、two array

1.两个有序链表合并(LC21)

1)题目
Merge two sorted linked lists and return it as a sorted list. The list should be made by splicing together the nodes of the first two lists.
2)思路
循环两个链表,插入值更小的那一个,结束后如果指向某个链表的指针非空,用结果指针指向它。
3)代码

ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    ListNode* root = new ListNode(-1);
    auto res = root;
    while (l1 && l2) {
        if (l1->val <= l2->val) {
            res->next = l1;
            l1 = l1->next;
        }
        else {
            res->next = l2;
            l2 = l2->next;
        }
        res = res->next;
    }
    if (l1) res->next = l1;
    if(l2) res->next = l2;
    return root->next;
}

2.两个有序array原地合并(LC88)

1)题目
You are given two integer arrays nums1 and nums2, sorted in non-decreasing order, and two integers m and n, representing the number of elements in nums1 and nums2 respectively.
Merge nums1 and nums2 into a single array sorted in non-decreasing order.
The final sorted array should not be returned by the function, but instead be stored inside the array nums1. To accommodate this, nums1 has a length of m + n, where the first m elements denote the elements that should be merged, and the last n elements are set to 0 and should be ignored. nums2 has a length of n.
2)思路
直接合并入第一个array,从后往前合并,不会override array1.
3)代码

void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
    int cur = m + n - 1;
    int i = m - 1, j = n - 1;
    while (i >= 0 && j >= 0) {
        while(i >= 0 && nums1[i] >= nums2[j]) nums1[cur--] = nums1[i--];
        while(i >= 0 && j >= 0 && nums2[j] >= nums1[i]) nums1[cur--] = nums2[j--];
    }
    while(j >= 0) nums1[cur--] = nums2[j--];
}

3.隐藏的有序array合并(LC977)

1)题目
Given an integer array nums sorted in non-decreasing order, return an array of the squares of each number sorted in non-decreasing order.
2)思路
相当于从0或者正数和负数的分界点往两边合并array,但是从两头合并更节省时间,不需要寻找0的位置;相当于也是从大到小合并。
3)代码

vector<int> sortedSquares(vector<int>& nums) {
    int n = nums.size();
    vector<int> res(n);
    int cur = n - 1;
    int i = 0, j = cur;
    while (i <= j) {
        if (nums[i] * nums[i] >= nums[j] * nums[j]) {
            res[cur--] = nums[i] * nums[i];
            i++;
        }
        else {
            res[cur--] = nums[j] * nums[j];
            j--;
        }
    }
    return res;
}

二、合并k个array(LC23)

1.题目
You are given an array of k linked-lists lists, each linked-list is sorted in ascending order.
Merge all the linked-lists into one sorted linked-list and return it.
2.思路
1)分治:两个两个合并,利用two array merge的方法
2)priority_queue:放入每个链表的头结点,依次取出值最小的进行链接
两种方法复杂度都是nlogk
3.做法
1)分治

ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    ListNode* root = new ListNode(-1);
    auto res = root;
    while (l1 && l2) {
        if (l1->val <= l2->val) {
            res->next = l1;
            l1 = l1->next;
        }
        else {
            res->next = l2;
            l2 = l2->next;
        }
        res = res->next;
    }
    if (l1) res->next = l1;
    if(l2) res->next = l2;
    return root->next;
}

ListNode* mergeKLists(vector<ListNode*>& lists) {
    
    int k = lists.size();
    if (!k) return NULL;
    while(k > 1) {
        int i = 0;
        for (i = 0; i + 1 < k; i += 2) {
            lists[i / 2] = mergeTwoLists(lists[i], lists[i + 1]);
        }
        if (i == k - 1) lists[k / 2] = lists[i];
        k = k / 2 + k % 2;
    }
    return lists[0];
}

2)priority_queue

struct cmp{
    bool operator ()(ListNode* a, ListNode* b) {
        return a->val > b->val;
    }
};

ListNode* mergeKLists(vector<ListNode*>& lists) {
    priority_queue<ListNode*, vector<ListNode*>, cmp> q;
    ListNode* ans = new ListNode(-1);
    auto root = ans;
    for (auto t: lists) {
        if(t) q.push(t);
    }
    while(q.size()) {
        auto t = q.top();
        q.pop();
        root->next = t;
        root = root->next;
        if(t->next) {
            t = t->next;
            q.push(t);
        }
    }
    return ans->next;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值