Leetcode Everyday: 88. Merge Sorted Array

本文介绍了一种将两个已排序数组合并为一个排序数组的方法,并进一步探讨了如何合并k个已排序数组的问题。对于后者,提出了两种解决方案:朴素解法的时间复杂度为O(nkLognk),改进方法的时间复杂度为O(nkLogk)。

https://leetcode.com/problems/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 nums1and nums2 are m and n respectively.

public class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int k = m+n-1;
        int i = m-1; int j = n-1;
        while(i>=0&&j>=0){
            if(nums1[i]>=nums2[j]){
                nums1[k]=nums1[i];
                i--;
            }else{
                nums1[k]=nums2[j];
                j--;
            }
            k--;
        }
        if(i==-1){
            while(j>=0){
                nums1[j]=nums2[j];
                j--;
            }
        }else{
            while(i>=0){
                nums1[i]=nums1[i];
                i--;
            }
        }
    }
}
To manipulate the array backwards.

An extended question is about how to merge k sorted arrays/lists.

The web page http://algorithms.tutorialhorizon.com/merge-k-sorted-arrays/ clearly stated the method.

Naive Solu­tion: O(nkLognk)

  • Cre­ate an result[] of size n*k.
  • Copy all the ele­ments from k arrays into result array. This will take O(nk).
  • Sort the result[] using Merge Sort. This will take O(nkLognk) time.

Bet­ter Approach: O(nkLogk)

Merge K Sorted Arrays

Merge K Sorted Arrays

  • Cre­ate an result[] of size n*k.
  • Cre­ate Min-Heap of type HeapN­ode.( HeapN­ode– Every Node will store the data and the list no from which it belongs).
  • Now take one ele­ment from each of the K list and cre­ate HeapN­ode object and insert into min-Heap.
  • Extract the min­i­mum Node from the min-Heap, insert the data into result array.
  • The extracted node will also con­tain the list to which it belongs, insert the next ele­ment from that list into min-Heap.
  • If any point of time any list gets over, insert +∞ into min-Heap.
  • Keep repeat­ing until all the K list gets over.
public class MergeKSortedArrays {

	public int size;
	public HeapNode[] Heap;
	public int position;
	int[] result;

	public MergeKSortedArrays(int k) {
		this.size = k;
		Heap = new HeapNode[k + 1]; // size+1 because index 0 will be empty
		position = 0;
		Heap[0] = new HeapNode(0, -1); // put some junk values at 0th index node
	}

	public int[] merge(int[][] A, int k, int n) {
		int nk = n * k;
		result = new int[nk];
		int count = 0;
		int[] ptrs = new int[k];
		// create index pointer for every list.
		for (int i = 0; i < ptrs.length; i++) {
			ptrs[i] = 0;
		}
		for (int i = 0; i < k; i++) {
			if (ptrs[i] < n) {
				insert(A[i][ptrs[i]], i); // insert the element into heap
			} else {
				insert(Integer.MAX_VALUE, i); // if any of this list burns out, insert +infinity
			}

		}
		while (count < nk) {
			HeapNode h = extractMin(); // get the min node from the heap.
			result[count] = h.data; // store node data into result array
			ptrs[h.listNo]++; // increase the particular list pointer
			if (ptrs[h.listNo] < n) { // check if list is not burns out
				insert(A[h.listNo][ptrs[h.listNo]], h.listNo); // insert the next element from the list
			} else {
				insert(Integer.MAX_VALUE, h.listNo); // if any of this list burns out, insert +infinity
			}
			count++;
		}
		return result;
	}

	public void insert(int data, int listNo) {
		if (position == 0) { // check if Heap is empty
			Heap[position + 1] = new HeapNode(data, listNo); // insert the first element in heap
			position = 2;
		} else {
			Heap[position++] = new HeapNode(data, listNo);// insert the element to the end
			bubbleUp(); // call the bubble up operation
		}
	}

	public HeapNode extractMin() {
		HeapNode min = Heap[1]; // extract the root
		Heap[1] = Heap[position - 1]; // replace the root with the last element in the heap
		Heap[position - 1] = null; // set the last Node as NULL
		position--; // reduce the position pointer
		sinkDown(1); // sink down the root to its correct position
		return min;
	}

	public void sinkDown(int k) {
		int smallest = k;
		// check which is smaller child , 2k or 2k+1.
		if (2 * k < position && Heap[smallest].data > Heap[2 * k].data) {
			smallest = 2 * k;
		}
		if (2 * k + 1 < position && Heap[smallest].data > Heap[2 * k + 1].data) {
			smallest = 2 * k + 1;
		}
		if (smallest != k) { // if any if the child is small, swap
			swap(k, smallest);
			sinkDown(smallest); // call recursively
		}

	}

	public void swap(int a, int b) {
		// System.out.println("swappinh" + mH[a] + " and " + mH[b]);
		HeapNode temp = Heap[a];
		Heap[a] = Heap[b];
		Heap[b] = temp;
	}

	public void bubbleUp() {
		int pos = position - 1; // last position
		while (pos > 0 && Heap[pos / 2].data > Heap[pos].data) { // check if its parent is greater.
			HeapNode y = Heap[pos]; // if yes, then swap
			Heap[pos] = Heap[pos / 2];
			Heap[pos / 2] = y;
			pos = pos / 2; // make pos to its parent for next iteration.
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[][] A = new int[5][];
		A[0] = new int[] { 1, 5, 8, 9 };
		A[1] = new int[] { 2, 3, 7, 10 };
		A[2] = new int[] { 4, 6, 11, 15 };
		A[3] = new int[] { 9, 14, 16, 19 };
		A[4] = new int[] { 2, 4, 6, 9 };
		MergeKSortedArrays m = new MergeKSortedArrays(A.length);
		int[] op = m.merge(A, A.length, A[0].length);
		System.out.println(Arrays.toString(op));
	}

}

// Every Node will store the data and the list no from which it belongs
class HeapNode {
	int data;
	int listNo;

	public HeapNode(int data, int listNo) {
		this.data = data;
		this.listNo = listNo;
	}
}
MergeKSortedArrays.java  hosted with  ❤  by  GitHub






评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值