88. Merge Sorted Array

本文介绍了一种不使用额外数组的两有序数组合并方法。通过遍历第二个数组并将其元素插入第一个数组的适当位置来实现合并,并提供了一种优化方案,即从后向前比较并放置较大值。

一、题意
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

Note:
You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively.
二、分析和解答
把第二个有序的数组 合并到第一个有序数组中(假设第一个数组的长度足够长),且让合并后的数组也保持有序。
1、由于不能使用额外的数组,所以通过一次比较把小的加入新数组的方法不可行了。暂时也没想出好的方法,所以直接来个暴力求解!遍历第二个数组的每一个元素,将其插入第一个数组的合适位置即可。假设它们都是递增的,如果第i个元素,插入过程:(插入的时候从后向前遍历)
若小于第一个数组的最后元素,将元素向后移动一位,一次向前;一直到比某个元素大的位置,结束循环;将其赋值。

public void merge(int[] nums1, int m, int[] nums2, int n) {
        for(int i=0;i<n;i++){
            int j;
            for(j=m-1;j>=0;j--){
                if(nums2[i] < nums1[j])
                    nums1[j+1] = nums1[j];
                else
                    break;//此时相等或者大于第j个元素
            }
            nums1[j+1] = nums2[i];//j后面的那个位置
            m = m + 1;//数组长度发生变化
        }
    }

Note:
(1)每次插入的时候,数组的长度都发生了变化;
(2)如果该值小于第一个数组某位置的值,让这个值后移一位;当大于或等于第一个数组某位置的值,直接结束循环,把该值放在某位置值的下一位即可。

2、优化
关键在于第一个数组后面的那段无用的空间!从两个数组元素的个数可以知道合并后数组最后的下标是m+n-1;然后,从后向前对两个数字的值进行比较,较大值放入最后下标对应的位置。

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

写成这样可能好理解:

        while(i>=0 && j>=0){
            if(nums1[i] > nums2[j]){
                nums1[k] = nums1[i];
                i--;
            }else{
                nums1[k] = nums2[j];
                j--;
            }
            k--;
        }

当然,也有人使用第三个额外的数组,合并后再赋值给数组一,但是那个不建议使用,这种方法肯定不是面试官想要的方法。

To merge k sorted linked lists, one approach is to repeatedly merge two of the linked lists until all k lists have been merged into one. We can use a priority queue to keep track of the minimum element across all k linked lists at any given time. Here's the code to implement this idea: ``` struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; // Custom comparator for the priority queue struct CompareNode { bool operator()(const ListNode* node1, const ListNode* node2) const { return node1->val > node2->val; } }; ListNode* mergeKLists(vector<ListNode*>& lists) { priority_queue<ListNode*, vector<ListNode*>, CompareNode> pq; for (ListNode* list : lists) { if (list) { pq.push(list); } } ListNode* dummy = new ListNode(-1); ListNode* curr = dummy; while (!pq.empty()) { ListNode* node = pq.top(); pq.pop(); curr->next = node; curr = curr->next; if (node->next) { pq.push(node->next); } } return dummy->next; } ``` We start by initializing a priority queue with all the head nodes of the k linked lists. We use a custom comparator that compares the values of two nodes and returns true if the first node's value is less than the second node's value. We then create a dummy node to serve as the head of the merged linked list, and a current node to keep track of the last node in the merged linked list. We repeatedly pop the minimum node from the priority queue and append it to the merged linked list. If the popped node has a next node, we push it onto the priority queue. Once the priority queue is empty, we return the head of the merged linked list. Note that this implementation has a time complexity of O(n log k), where n is the total number of nodes across all k linked lists, and a space complexity of O(k).
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值