[100天算法】-有序矩阵中第K小的元素(day 58)

news2024/11/28 13:39:23

题目描述

给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。
请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素。

 

示例:

matrix = [
   [ 1,  5,  9],
   [10, 11, 13],
   [12, 13, 15]
],
k = 8,

返回 13。
 

提示:
你可以假设 k 的值永远是有效的,1 ≤ k ≤ n2 。

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

方法1:归并排序

思路

矩阵的每一行都是一个升序的数组,用合并多个有序数组的思路,找出前 k 个最小的元素就行。

用 n 个指针来记录每一行当前最小元素。

复杂度分析

  • 时间复杂度:$O(k*n)$,n 是矩阵宽高,其中 k 最坏的情况下是 n2,所以最坏的时间复杂度是 O(n3)。
  • 空间复杂度:$O(n)$,指针数组的长度。

代码

JavaScript Code

/**
 * @param {number[][]} matrix
 * @param {number} k
 * @return {number}
 */
var kthSmallest = function (matrix, k) {
    const rows = matrix.length;
    const cols = matrix[0].length
    const indices = Array(rows).fill(0);

    let kth;
    while (k-- > 0) {
        let min = Infinity
        let minRow = -1
        for (let r = 0; r < rows; r++) {
            if (indices[r] >= cols) continue

            const num = matrix[r][indices[r]];
            if (num <= min) {
                min = num;
                minRow = r
            }
        }
        kth = min
        indices[minRow]++;
    }
    return kth;
};

方法2:归并排序+堆

思路

还是上一个方法的思路,只不过在寻找多行中的最小值时,不用循环查找,而是用堆将这个查找时间从 n 降到 logn。

复杂度分析

  • 时间复杂度:$O(klogn)$,n 是矩阵宽高,其中 k 最坏的情况下是 $n^2$,所以最坏的时间复杂度是 $O(n^2logn)$。
  • 空间复杂度:$O(n)$,堆的大小。

代码

JavaScript Code

/**
 * @param {number[][]} matrix
 * @param {number} k
 * @return {number}
 */
var kthSmallest = function (matrix, k) {
    const list = matrix.map((row, x) => [row[0], x, 0]);
    // 堆中的数据结构是 [num, x, y]
    const heap = new MinHeap(list, function comparator(inserted, compared) {
        return inserted[0] > compared[0];
    });
    
    while (k-- > 1) {
        const [, x, y] = heap.pop();
        if (y < matrix[0].length - 1) {
            heap.insert([matrix[x][y + 1], x, y + 1]);
        }
    }
    return heap.pop()[0];
};

// **************************************************

class Heap {
    constructor(list = [], comparator) {
        this.list = list;
        this.comparator = comparator;

        this.init();
    }

    init() {
        const size = this.size();
        for (let i = Math.floor(size / 2) - 1; i >= 0; i--) {
            this.heapify(this.list, size, i);
        }
    }

    insert(n) {
        this.list.push(n);
        const size = this.size();
        for (let i = Math.floor(size / 2) - 1; i >= 0; i--) {
            this.heapify(this.list, size, i);
        }
    }

    peek() {
        return this.list[0];
    }

    pop() {
        const last = this.list.pop();
        if (this.size() === 0) return last;
        const returnItem = this.list[0];
        this.list[0] = last;
        this.heapify(this.list, this.size(), 0);
        return returnItem;
    }

    size() {
        return this.list.length;
    }
}

class MinHeap extends Heap {
    constructor(list, comparator) {
        if (typeof comparator != 'function') {
            comparator = function comparator(inserted, compared) {
                return inserted > compared;
            };
        }
        super(list, comparator);
    }

    heapify(arr, size, i) {
        let smallest = i;
        const left = Math.floor(i * 2 + 1);
        const right = Math.floor(i * 2 + 2);
        if (left < size && this.comparator(arr[smallest], arr[left]))
            smallest = left;
        if (right < size && this.comparator(arr[smallest], arr[right]))
            smallest = right;

        if (smallest !== i) {
            [arr[smallest], arr[i]] = [arr[i], arr[smallest]];
            this.heapify(arr, size, smallest);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1172472.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何实现多租户系统

shigen日更文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 不知道为什么&#xff0c;最近老是有一些失眠&#xff0c;凌晨睡&#xff0c;两点半还在醒着。脑子里想着自己生…

手动关闭PS中的TopazStudio2的登录窗口

2021 adobe photoshop Topaz Studio 2 不是使用防火墙出站规则&#xff0c;是手动关闭的解决方案 点击社区-切换用户&#xff0c;登录窗口会出现X&#xff0c;可以手动关闭

VBA根据Excel内容快速创建PPT

示例需求&#xff1a;根据Excel中选中的单元格内容&#xff08;3列&#xff09;如下图所示&#xff0c;在已打卡的PowerPoint文件中创建页面。 新增PPT Slide页面使用第二个模板页面&#xff0c;其中包含两个文本占位符&#xff0c;和一个图片占位符。将Excel选中区域中前两列写…

Nginx 配置详细讲解

Nginx.conf 配置文件分为三部分&#xff0c;分别为main块、events块、http块&#xff08;http块又包含server块和location块&#xff09;&#xff0c;如下图。 第一部分&#xff1a;main块(全局块) main块主要是设置一些影响Nginx服务器整体运行的配置指令&#xff0c;主要包括…

2.8 CSS 伸缩盒模型

1.模型简介 传统布局是指:基于传统盒状模型&#xff0c;主要靠: display 属性 position 属性float 属性。2009年&#xff0c;w3C提出了一种新的盒子模型——Flexible Box(伸缩盒模型&#xff0c;又称:弹性盒子)。它可以轻松的控制:元素分布方式、元素对齐方式、元素视觉顺序..…

0008Java安卓程序设计-ssm基于Android平台的健康管理系统

文章目录 **摘要**目录系统实现开发环境 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;776871563 摘要 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,…

那些看起来高大上的封装函数

什么 ToGray 只支持3通道图像&#xff0c; 让我看看怎么个事 就这么生硬的加了个判断 好家伙 调用了下opencv &#xff0c;通道数都不判断一下

Java多线程面试题:如何在多个子线程中捕获异常并引发主线程异常?

亲爱的小伙伴们&#xff0c;大家好&#xff01;我是你们的小米&#xff0c;今天我要和大家分享一个热门的技术话题——"面试题&#xff1a;多个子线程中&#xff0c;其中一个子线程异常时主线程如何抛出异常并返回&#xff1f;"。这是在面试中经常被问到的问题&#…

【多线程】Lambda表达式

package org.example;public class TestLambda {public static void main(String[] args) {Like likenew Like();like.lambda();}}//定义一个函数式接口 interface ILike{void lambda(); }//实现类 class Like implements ILike{Overridepublic void lambda() {System.out.prin…

Vue Vue3

1、创建VUE3工程 使用vue-cli创建&#xff1a; ## 查看vue/cli版本&#xff0c;确保vue/cli版本在4.5.0以上 vue --version ## 安装或者升级你的vue/cli npm install -g vue/cli ## 创建 vue create vue_test ## 启动 cd vue_test npm run serve 使用vite创建&#xff1a; …

【笔记】单片机卡死的八大原因和解决方法

在微控制器上&#xff0c;程序卡住&#xff08;即停止执行&#xff09;可能有多种原因。下面我将列举一些常见的原因&#xff0c;并提供一些可能导致程序卡住的示例情况。请注意&#xff0c;这里只是一些示例&#xff0c;并不能穷尽所有可能的情况。 1. 死循环&#xff08;Infi…

基于若依的ruoyi-nbcio流程管理系统增加仿钉钉流程设计(六)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 这节主要讲条件节点与并发节点的有效性检查&#xff0c;主要是增加这两个节点的子节点检查&#xff0c;因为…

C/C++输出字符菱形 2021年3月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C输出字符菱形 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C输出字符菱形 2021年3月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 给定一个字符&#xff0c;用它构造一个对角线长…

学习c++的第十天

目录 类 & 对象 类定义 对象的建立和使用 构造函数(Constructor) 析构函数(Destructor) 拷贝构造函数 扩展知识 this指针 友元函数的使用方法 友元类的使用方法 常数据的使用及初始化 类 & 对象 什么是类&#xff1f;什么是对象&#xff1f;对于面向对象的…

【黑马程序员】SSM框架——SpringBoot(未完成)

文章目录 前言一、SpringBoot 简介1. 入门案例1.1 入门程序① 创建新模块② 选择当前模块需要使用的技术集③ 开发控制类④ 运行自动生成的 Application 类 1.2 创建 SpringBoot 程序的两种方式1.2.1 最简 SpringBoot 程序所包含的基础文件1.2.2 基于 SpringBoot 官网创建项目 …

vue3后台管理系统之实现分页功能

例子&#xff1a;用户 请求格式 返回数据类型 {"code": 200,"message": "获取所有用户成功","total": 19,"totalPages": 2,"currentPage": 1,"data": [{"id": 1,"username": &qu…

6-8 最宽层次结点数 分数 10

文章目录 1.题目描述2.本题ac答案2.1法一: 代码复用2.2法二: 顺序队列实现层序遍历 3.C层序遍历求最大宽度3.1层序遍历代码3.2求最大宽度 1.题目描述 2.本题ac答案 2.1法一: 代码复用 //二叉树第i层结点个数 int LevelNodeCount(BiTree T, int i) {if (T NULL || i < 1)re…

CleanMyMacX4.16破解版激活码

CleanMyMac X是一款颇受欢迎的专业清理软件&#xff0c;拥有十多项强大的功能&#xff0c;可以进行系统清理、清空废纸篓、清除大旧型文件、程序卸载、除恶意软件、系统维护等等&#xff0c;并且这款清理软件操作简易&#xff0c;非常好上手&#xff0c;特别适用于那些刚入手苹…

卡尔曼家族从零解剖-(04)贝叶斯滤波→细节讨论,逻辑梳理,批量优化

讲解关于slam一系列文章汇总链接:史上最全slam从零开始&#xff0c;针对于本栏目讲解的 卡尔曼家族从零解剖 链接 :卡尔曼家族从零解剖-(00)目录最新无死角讲解&#xff1a;https://blog.csdn.net/weixin_43013761/article/details/133846882 文末正下方中心提供了本人 联系…

C++虚表与虚表指针详解

类的虚表 每个包含了虚函数的类都包含一个虚表。 当一个类&#xff08;B&#xff09;继承另一个类&#xff08;A&#xff09;时&#xff0c;类B会继承类A的函数的调用权。所以如果一个基类包含了虚函数&#xff0c;那么其继承类也可调用这些虚函数&#xff0c;换句话说&…