LeetCode 373 Find K Pairs with Smallest Sums

You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.

Define a pair (u,v) which consists of one element from the first array and one element from the second array.

Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.

Example 1:

Given nums1 = [1,7,11], nums2 = [2,4,6],  k = 3

Return: [1,2],[1,4],[1,6]

The first 3 pairs are returned from the sequence:
[1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]

Example 2:

Given nums1 = [1,1,2], nums2 = [1,2,3],  k = 2

Return: [1,1],[1,1]

The first 2 pairs are returned from the sequence:
[1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]

Example 3:

Given nums1 = [1,2], nums2 = [3],  k = 3 

Return: [1,3],[2,3]

All possible pairs are returned from the sequence:
[1,3],[2,3]

         优先级队列是不同于先进先出队列的另一种队列,每次从队列中取出的是具有最高优先权的元素。如果不提供Comparator的话,优先队列中元素默认按自然顺序排列,也就是数字默认是小的在队列头,字符串则按字典序排列。PriorityQueue本质上就是堆排序里面建的最小堆,最小堆满足的一个基本性质是堆顶端的元素是所有元素里最小的那个。堆排序只能保证根是最小(最大),不能保证整体是按照顺序来排序的,只是保证新加入的元素和最近的节点是排序的。

        如果想实现按照自己的意愿进行优先级排列的队列的话,需要实现Comparator接口。下面的方法,利用了lambda实现了根据变量sum,来进行优先级队列的建立。

建立类Pair

	class Pair {
		int[] pair;
		int idx2; // current index to nums2
		long sum;

		Pair(int idx2, int n1, int n2) {
			this.idx2 = idx2;
			pair = new int[]{n1, n2};
			sum = (long) n1 + (long) n2;
		}
	}

84ms,beats 20%

	public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
		List<int[]> result = new ArrayList<>();
		if (nums1 == null || nums2 == null || nums1.length == 0 || nums2.length == 0) return result;
		PriorityQueue<Pair> heap = new PriorityQueue<>(k, (a, b) -> (Long.compare(a.sum, b.sum));
		for (int i = 0; i < nums1.length && i < k; i++) { // only need first k number in nums1 to start
			heap.offer(new Pair(0, nums1[i], nums2[0]));
		}
		for (int i = 0; i < k && !heap.isEmpty(); i++) { // get the first k sums
			Pair p = heap.poll();//get the current smallest pair in heap
			result.add(p.pair);
			if (p.idx2 < nums2.length - 1) { // get the next value in nums2
				int next = p.idx2 + 1;
				heap.offer(new Pair(next, p.pair[0], nums2[next]));
			}
		}
		return result;
	}

PriorityQueue<Pair> heap = new PriorityQueue<>(k, (a, b) -> (Long.compare(a.sum, b.sum));这里使用的是lambda表达式,性能居然比重新实现 Comparator低。

8ms,beats 92.39%

  
	class CompPair implements Comparator<Pair> {
		public int compare(Pair p1, Pair p2) {
			return Long.compare(p1.sum, p2.sum);
		}
	}

	public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
		List<int[]> result = new ArrayList<>();
		if (nums1 == null || nums2 == null || nums1.length == 0 || nums2.length == 0) return result;
		PriorityQueue<Pair> heap = new PriorityQueue(k, new CompPair());
		for (int i = 0; i < nums1.length && i < k; i++) { // only need first k number in nums1 to start
			heap.offer(new Pair(0, nums1[i], nums2[0]));
		}
		for (int i = 0; i < k && !heap.isEmpty(); i++) { // get the first k sums
			Pair p = heap.poll();//get the current smallest pair
			result.add(p.pair);
			if (p.idx2 < nums2.length - 1) { // get the next value in nums2
				int next = p.idx2 + 1;
				heap.offer(new Pair(next, p.pair[0], nums2[next]));
			}
		}
		return result;
	}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值