zoukankan      html  css  js  c++  java
  • 【leetcode】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]

    题目的意思很简单,给定两个升序排列的数组,从两个数组中各取一个元素进行配对,并对配对的两个进行求和,找出前K小的配对组合。

    最直接的办法就是穷举,把所有的组合都列出来,得到最后的结果,这样的时间复杂度是N^2。那么有没有更简单的方法呢?

    由于数组是有序的,那么最小的一个配对组合肯定是 [nums1[0],nums2[0] ],并且 [nums1[i],nums2[j] ] 一定小于 [nums1[i],nums2[j+1] ]。知道这个规律后,次小的配对组合一定是在 [nums1[0],nums2[1] ] ...[nums1[i-1],nums2[0] ],  [nums1[i],nums2[0] ]之间产生。假设次小的值是 [nums1[i-1],nums2[0] ],那么第三小的值就是在 [nums1[0],nums2[1] ] ...[nums1[i-1],nums2[1] ],  [nums1[i],nums2[0] ]。

    所以,我们只需要再维护一个数组A,数组中下标对应nums1的下标,数组对应的值对应nums2的下标。每次只需要循环数组A,计算 nums[X] + nums[A[X]],得到其中的最小值nums[X] + nums[A[X]]就是当前最小配对。找到最小配对后把数组A的A[x] 的值 +1,继续循环,直到找到第K个配对元素为止。

    下面是参考代码:

    /**
     * Created by Administrator on 2016/7/25.
     */
    /**
     * @param {number[]} nums1
     * @param {number[]} nums2
     * @param {number} k
     * @return {number[][]}
     */
    var kSmallestPairs = function(nums1, nums2, k) {
        if (nums1.length == 0 || nums2.length == 0){
            return []
        }
        var count = 0;
        var list = [];
        for (var i = 0;i<nums1.length;i++){
            list.push(0)
        }
    
        var result = []
        result.push([nums1[0],nums2[0]])
        list[0] = 1
        while( k > result.length && result.length < nums1.length*nums2.length){
            //console.log(k,result.length)
            var minIndex = 0;
            var minSum = 0;
            var j = 0;
            for(j = 0;j<list.length;j++){
                if (list[j] < nums2.length){
                    break
                }
            }
            minSum = nums1[j] + nums2[list[j]]
            for(var i = 0;i<list.length;i++){
                if(minSum >= nums1[i] + nums2[list[i]]){
                    minIndex = i
                    minSum = nums1[i] + nums2[list[i]]
                }
            }
            //console.log(minIndex)
            result.push([nums1[minIndex],nums2[list[minIndex]]])
            list[minIndex] ++;
        }
        return result
    
    };
  • 相关阅读:
    no,no,不要使用kill -9
    Linux中etc目录详解
    Quartz任务调度器的使用
    RMI(Remote Method invocation,远程方法访问)
    SilverLight扩展控件RadTreeView
    SiverLight和HTML交互
    SilverLight控件之ContextMenu和RadContextMenu(菜单)
    SilverLight之向后台请求数据-WebClient
    SilverLight控件样式及控件模版
    在SilverLight中代码编写可选择树节点
  • 原文地址:https://www.cnblogs.com/seyjs/p/5703840.html
Copyright © 2011-2022 走看看