首页 > 其他分享 >1439. 有序矩阵中的第 k 个最小数组和

1439. 有序矩阵中的第 k 个最小数组和

时间:2023-05-31 11:24:36浏览次数:60  
标签:tmp arr int sum 矩阵 1439 ++ length 数组

给你一个 m * n 的矩阵 mat,以及一个整数 k ,矩阵中的每一行都以非递减的顺序排列。

你可以从每一行中选出 1 个元素形成一个数组。返回所有可能数组中的第 k 个 最小 数组和。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-the-kth-smallest-sum-of-a-matrix-with-sorted-rows
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

class Solution {

    private int[] merge(int[] a, int[] b, int k) {
        if (a.length < b.length) {
            return merge(b, a, k);
        }
        PriorityQueue<Node> queue = new PriorityQueue<>(new Comparator<Node>() {
            @Override
            public int compare(Node o1, Node o2) {
                return Integer.compare(o1.sum, o2.sum);
            }
        });
        for (int i = 0; i < b.length && i < k; i++) {
            queue.offer(new Node(0, i, a[0] + b[i]));
        }

        List<Integer> tmp = new ArrayList<>();
        while (tmp.size() < k && !queue.isEmpty()) {
            Node node = queue.poll();
            tmp.add(node.sum);
            if (node.aIndex < a.length - 1) {
                node.aIndex++;
                node.sum = a[node.aIndex] + b[node.bIndex];
                queue.offer(node);
            }
        }
        int[] ans = new int[tmp.size()];
        for (int i = 0; i < tmp.size(); i++) {
            ans[i] = tmp.get(i);
        }
        return ans;
    }

    public int kthSmallest(int[][] mat, int k) {
        int[] arr = mat[0];
        for (int i = 1; i < mat.length; i++) {
            arr = merge(arr, mat[i], k);
        }
        return arr[k - 1];
    }
}

class Node {
    int aIndex;
    int bIndex;
    int sum;

    public Node(int aIndex, int bIndex, int sum) {
        this.aIndex = aIndex;
        this.bIndex = bIndex;
        this.sum = sum;
    }
}

二分

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Solution {

    private int upper(int[] arr, int key) {
        int left = 0, right = arr.length - 1;
        while (left <= right) {
            int mid = (left + right) >> 1;
            if (arr[mid] <= key) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return left;
    }

    private int[] merge(int[] a, int[] b, int k) {
        if (a.length < b.length) {
            return merge(b, a, k);
        }
        k = Math.min(k, a.length * b.length);
        int left = a[0] + b[0], right = a[a.length - 1] + b[b.length - 1];
        int sum = 0;
        while (left <= right) {
            int mid = (left + right) >> 1;
            int cnt = 0;
//            for (int i = 0; i < a.length; i++) {
//                cnt += upper(b, mid - a[i]);
//            }
            int j = b.length - 1;
            for (int i = 0; i < a.length; i++) {
                while (j >= 0 && a[i] + b[j] > mid) {
                    j--;
                }
                cnt += j + 1;
            }
            if (cnt >= k) {
                sum = mid;
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        List<Integer> tmp = new ArrayList<>();
        for (int i = 0; i < a.length && tmp.size() < k; i++) {
            for (int j = 0; j < b.length && tmp.size() < k; j++) {
                if (a[i] + b[j] < sum) {
                    tmp.add(a[i] + b[j]);
                }
            }
        }

        while (tmp.size() < k) {
            tmp.add(sum);
        }

        Collections.sort(tmp);
        int[] ans = new int[tmp.size()];
        for (int i = 0; i < tmp.size(); i++) {
            ans[i] = tmp.get(i);
        }
        return ans;
    }

    public int kthSmallest(int[][] mat, int k) {
        int[] arr = mat[0];
        for (int i = 1; i < mat.length; i++) {
            arr = merge(arr, mat[i], k);
        }
        return arr[k - 1];
    }
}

标签:tmp,arr,int,sum,矩阵,1439,++,length,数组
From: https://www.cnblogs.com/tianyiya/p/17445544.html

相关文章

  • 二分法应用——搜索旋转数组,以前一直在纠结a[0],a[-1],a[mid], target三者关系,其实最
    62·搜索旋转排序数组  描述给定一个有序数组,但是数组以某个元素作为支点进行了旋转(比如,0124567可能成为4567012)。给定一个目标值target进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回-1。你可以假设数组中不存在重复的元素。背完这套刷题模板,真......
  • 多维数组遍历
    #include<stdio.h>intmain(){intarr[][3]={{1,2},{3,4,5}};inti=0;intj=0;intlen=0;for(i=0;i<2;i++){for(j=0;j<3;j++){printf("arr[%d][%d]:%d",i,j,arr[i][j]);}prin......
  • heapq 对有序的数组列表进行整体排序
     """功能:实现对有序的多个数组整体排序,获取topk个最小元素"""fromheapqimport*defheap_sort(arr,top_k):q=[]foriinrange(len(arr)):heappush(q,(arr[i][0],i,0))result=[]forkinrange(top_k):ifq:......
  • Gym - 101174F[(DSU)+树状数组]
    题目链接:https://vjudge.net/problem/Gym-101174F 解题思路:其实这题不同启发式合并也可以做,对rank排个序,然后在做个dfs序,把rank值小的先插入树状数组中更新,然后对每个节点查询它的dfs序的区间和就好了。对于DSU来说就更加无脑了,本来就是"暴力",所以我们直接DSU再加一个树状数组维......
  • python二维数组切片
    随堂测试这道题错了,于是怒而发blog,是分割维度的标识符,如果对象是二维数组,则切片应当是x[,]的形式,逗号之前和之后分别表示对象的第0个维度和第1个维度;如果对象是三维数组,则切片应当是x[,,],里面有两个逗号,分割出三个间隔,三个间隔的前、中和后分别表示对象的第0、1、2个维度。每个......
  • wukong引擎源码分析之索引——part 1 倒排列表本质是有序数组存储
    searcher.IndexDocument(0,types.DocumentIndexData{Content:"此次百度收购将成中国互联网最大并购"})engine.go中的源码实现://将文档加入索引////输入参数://docId标识文档编号,必须唯一//data见DocumentIndexData注释////注意://1.这个函数是线程安全......
  • python二维数组初始化
    >>>a=[[0]*3foriinrange(3)]>>>a[[0,0,0],[0,0,0],[0,0,0]]>>>a[1][1]=121>>>a[[0,0,0],[0,121,0],[0,0,0]]>>>a[0][0]=11>>>a[[11,0,0],[0,121,0],[0,0,0]]>>>......
  • 数组中找最大值
    数组中找最大值#include<stdio.h>intmain(){ inta[]={3,2,5,8,4,7,6,9}; intlen=sizeof(a)/sizeof(a[0]); intmax=a[0]; for(inti=1;i<len;i++){ if(a[i]>max){ max=a[i]; } } printf("%d",max); retur......
  • 一维数组的动态和
    给你一个数组nums。数组「动态和」的计算公式为:runningSum[i]=sum(nums[0]…nums[i])。请返回nums的动态和。示例1:输入:nums=[1,2,3,4]输出:[1,3,6,10]解释:动态和计算过程为[1,1+2,1+2+3,1+2+3+4]。示例2:输入:nums=[1,1,1,1,1]输出:[1,2,3,4,5]解释:动态和......
  • 差分数组,经常在数组某段区间内统一进行加减相同值
    假设某一数组d经常做在某一段区间[a,b]内统一进行加减的操作,由于每次进行操作都需要从a循环遍历到b,时间开销较大,所以可以采用差分数组来解决此类问题.设数组d[]={8,1,3,6,5,4,2}当需要在区间[0,3]上统一加3时,不采用循环的方式,而是新创建一数组c,初始每个下标上的值均为0,则:......