And the smallest (largest) and smallest k number pairs - java heap solution (priority queue)

topic

insert image description here

Given two integer arrays nums1 and nums2 in ascending order, and an integer k.
Defines a pair of values ​​(u,v) where the first element is from nums1 and the second element is from nums2.
Please find the smallest k pairs of numbers (u1,v1), (u2,v2) … (uk,vk).

analyze

Big root heap (big top heap): Big root heap means that in a logical binary tree structure, the root node > child node is always the largest, and it is like this in every part of the heap.

Small root heap (small top heap): Contrary to the big root heap, that is, all local roots are smaller than child nodes.
insert image description here
Priority queues are implemented using heaps in java.
There are two main categories

  1. PriorityQueuethread unsafe
  2. PriorityBlockingQueuethread safety

I use it here PriorityQueue. For this question, we can maintain an answer sequence through a large top heap.

The Jdk priority queue allows us to customize the comparator, and the objects that can be compared are the comparison conditions that can use the priority queue

PriorityQueueThe default implementation is a small top heap, here we implement a large top heap

                PriorityQueue<List<Integer>> queue = new PriorityQueue<List<Integer>>(new Comparator<List<Integer>>() {
    
    
	            public int compare(List<Integer> m, List<Integer> n) {
    
    
	                if(m.get(0) + m.get(1) < n.get(0) + n.get(1)){
    
    
                        return 1;
                    }else{
    
    
                        return -1;
                    }
	            }
	        });

At this point, we can perform two for loops

class Solution {
    
    
    public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
    
    
        List<List<Integer>>result = new ArrayList<>();
        //构造有些队列,自定义比较器
                PriorityQueue<List<Integer>> queue = new PriorityQueue<List<Integer>>(new Comparator<List<Integer>>() {
    
    
	            public int compare(List<Integer> m, List<Integer> n) {
    
    
	                if(m.get(0) + m.get(1) < n.get(0) + n.get(1)){
    
    
                        return 1;
                    }else{
    
    
                        return -1;
                    }
	            }
	        });
	        //两次for循环,向优先队列中添加值
        for(int i = 0; i < nums1.length; i++){
    
    
            for(int j = 0; j < nums2.length; j++){
    
    
                if(queue.size() < k){
    
    
                    queue.offer(Arrays.asList(nums1[i],nums2[j]));
                }else{
    
    
                    if(nums1[i] + nums2[j] < queue.peek().get(0) + queue.peek().get(1)){
    
    
                        queue.poll();
                        queue.offer(Arrays.asList(nums1[i],nums2[j]));
                    
                    }else{
    
    
                        if(nums1[i] > queue.peek().get(0) && nums2[j] > queue.peek().get(1)){
    
    
                            break;
                        }
                    }
                }
            }
        }
        for(List<Integer>list : queue){
    
    
            result.add(list);
        }
        return result;

    }
}

Some people may ask, why don't I directly traversal through the two for loops

Because: we maintain an answer sequence and know the maximum or minimum value, we can easily eliminate some invalid and unnecessary traversals, such as:

When the new values ​​of array 1 and array 2 are greater than the maximum value at the top of the heap in the maintained answer queue, this traversal is unnecessary, and this small loop can end.

if(nums1[i] > queue.peek().get(0) && nums2[j] > queue.peek().get(1)){
    
    
                            break;
                        }

at last:

Then I finally give some explanations of commonly used methods:

1. boolean add(object)//将指定的元素插入此优先级队列。

2. boolean offer(object)//将指定的元素插入此优先级队列。

3. boolean remove(object)//从此队列中删除指定元素的单个实例(如果存在)。

4. Object poll()//检索并删除此队列的头部,如果此队列为空,则返回null。

5.Object element()//检索但不删除此队列的头部,如果此队列为空,则返回null。

6.Object peek()//检索但不删除此队列的头部,如果此队列为空,则返回null。

7. void clear()//从此优先级队列中删除所有元素。

8. Comparator comparator()//返回用于对此队列中的元素进行排序的比较器,如果此队列根据其元素的自然顺序排序,则返回null。

9. boolean contains(Object o) //如果此队列包含指定的元素,则返回true。

10.Iterator iterator() //返回此队列中元素的迭代器。

11.int size()//返回此队列中的元素数。

12.Object [] toArray()//返回包含此队列中所有元素的数组。

Guess you like

Origin blog.csdn.net/faker1234546/article/details/129622801