当前位置: 首页 > article >正文

杨氏矩阵找第N大(小)的O(N)线性算法 LeetCode 378. Kth Smallest Element in a Sorted Matrix 373. Find K Pairs 钓鱼问题

杨氏矩阵一个N*N的矩阵它的每行每列都单调递增(或者宽松一些,单调不减)即a[i][j]a[i1][j], a[i][j]a[i][j1]。遇到的两道面试题1. 输出杨氏矩阵中最小的N个数。2. 两个升序数组A和B长度都是N。从两个数组中分别取出一个数相加得到一个和。求这N*N个和的前N小。本质上第2题可以转化成第一题把A[0]B[k]的结果填入矩阵第一行A[1]B[k]的结果填入第二行……就得到一个杨氏矩阵。所以现在就只考虑第1题咯。此题常见的一种做法N路归并用一个大小为N的堆可以O(NlgN)得到解。但是利用杨氏矩阵的性质这题是有O(N)的算法的……为了方便把矩阵记为num首先根据杨氏矩阵的性质得到最关键的一点前N小的数肯定不大于矩阵中的num[sqrt(N)1][sqrt(N)1]。为了方便令M sqrt(N)1因此要找的前N小的数肯定在矩阵的前M行和前M列中。所以要找的是一个M*N的矩阵和另外一个(N-M)*M的矩阵。这样的规模相当于M*(2N-M)相当于M*N这样问题可以转化为在M个长度为N的有序数组中查找前N小的数。(*)除了之前提到的方法此题还有一个比较容易想到的方法二分上界并计数。在INT_MIN~INT_MAX中二分第K大数的上界每次对所有数组二分统计其中不大于上界的数的个数。总体的复杂度是O(R*M*lgN)。其中R是最坏情况下二分的次数。对于32位整数最多二分32次R32。但是对于浮点数需要的二分次数会增多。在这个思路的基础上加以改进把R改进为lgN便可得到线性算法。基本思路是把二分时取数的范围从INT_MIN~INT_MAX缩小到这MN个数中。每次从这些数中选一个来作为计数的上界。选的方法每一轮计数时先找出这M个数组的中位数作为每个数组潜在的切分点然后选择这些切分点的中位数作为上界。O(M)选出M个切分点O(MlgM把这些数排个序再选中间的所以这一步可以O(MlgM)注无序数组选中位数有均摊O(M)的算法。但是为了每一轮都能缩小查找范围所以对于每个数组还要维护一个“潜在切分点的可能区间”选择该数组的新切分点时取这个区间的中位数。实际上就是对每个数组维护一个二分切分点的过程信息。这样一轮统计过后某些偏大或偏小的切分点所在区间长度就需要减半。并且至少有半数区间的长度是要减半的。对于一个数组不大于中位数的数的个数至少是一半。“不小于”同理由于所有数组一共有MN个数因此在lg(MN)轮后所有区间长度都会减到1。整理一下复杂度。一共要进行lg(MN)次计数每次计数需要O(MlgM)找切分点的中位数以及O(MlgN)对一个数组计数。因此整体的复杂度是O(lg(MN)*(MlgMMlgN)) O(sqrt(N)*(lgN)^2) o(sqrt(N)*sqrt(N)) o(N)ps. 所以这个算法复杂度其实是低于O(N)的.(*)附代码用以上算法实现在M个有序数组中查找第K小的数。转自http://wolf5x.cc/blog/algorithm/young-tableau-smallest-kth#comment-123#include iostream #include vector #include algorithm using namespace std; // i, partition_point_lower_index_i, partition_point_upper_index_i typedef pairint, pairint,int PartRange; typedef vectorvectorint VVI; class PartComparator { const VVI ary; public: PartComparator(const VVI a): ary(a){} bool operator()(const PartRange x, const PartRange y) const { return ary[x.first][(x.second.firstx.second.second)/2] ary[y.first][(y.second.firsty.second.second)/2]; } }; // Get the count of numbers less than or equal to upper int getCount(VVI num, int upper) { int ret 0; for (int i 0; i num.size(); i) { ret upper_bound(num[i].begin(), num[i].end(), upper) - num[i].begin(); } return ret; } int chooseKthSmallest(VVI num, int k) { int n num.size(); vectorPartRange part(n); for (int i 0; i n; i) { part[i] make_pair(i, make_pair(0, num[i].size()-1)); } int ans 130; // INT_MAX; while(part.size() 0) { // sort all the medians sort(part.begin(), part.end(), PartComparator(num)); // choose the median of medians int mid part.size()/2; int upper num[part[mid].first][(part[mid].second.firstpart[mid].second.second)/2]; int count getCount(num, upper); if (count k) { // update answer ans min(ans, upper); // halve the median intervals of which the median is too large for(int i 0; i part.size(); i) { int mid (part[i].second.firstpart[i].second.second)/2; if (num[part[i].first][mid] upper) { part[i].second.second mid-1; } } } else { // halve the median intervals of which the median is too small for (int i 0; i part.size(); i) { int mid (part[i].second.firstpart[i].second.second)/2; if (num[part[i].first][mid] upper) { part[i].second.first mid1; } } } // remove the empty median intervals for (int i part.size()-1; i 0; i--) { if (part[i].second.first part[i].second.second) { swap(part[i], part[part.size()-1]); part.erase(part.end()-1); } } } return ans; } int main() { int v[][3] {{1,2,3},{2,3,4},{3,4,5}}; vectorint vec0(v[0],v[0]3); vectorint vec1(v[1],v[1]3); vectorint vec2(v[2],v[2]3); int arr[] {1,2,2,3,4,4,4,4,5,6,7,8,9,9,10}; vectorint vec3(arr, arrsizeof(arr)/sizeof(int)); VVI num; num.push_back(vec0); num.push_back(vec1); num.push_back(vec2); int up distance(vec3.begin(), upper_bound(vec3.begin(), vec3.end(), 11)); int low distance(vec3.begin(), lower_bound(vec3.begin(), vec3.end(), 11)); int res chooseKthSmallest(num, 3); return 0; }--------------------------------------------------------------------------------------------------------很久之后发现一种更好的解法仍然二分假设数据二分的范围是整个整数那么log(2^32)次最多是32次实际中范围可以由左上角和右下角来确定anyway二分的次数可以看做是一个常数。。。剩下的问题就是给定一个target求这个matrix中target的元素个数这个是可以O(n)实现的也就是从右上角开始往下找。。所以整体复杂度是O(n)。LeetCode上恰好有这么一道题Given anxnmatrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix.Note that it is the kth smallest element in the sorted order, not the kth distinct element.Example:matrix [ [ 1, 5, 9], [10, 11, 13], [12, 13, 15] ], k 8, return 13.Note:You may assume k is always valid, 1 ≤ k ≤ n2.-----------------------------------------------------------class Solution: def count_lower(self, nums, target, n): j, res n - 1, 0 for i in range(n): while (j 0 and nums[i][j] target): j - 1 res (j 1) return res def kthSmallest(self, matrix, k: int) - int: n len(matrix) left, right matrix[0][0], matrix[n - 1][n - 1] while (left right): target ((right - left) 1) left lower self.count_lower(matrix, target, n) if (lower k): left target 1 else: right target - 1 return left------------------------------------------------另外一道题要求输出也排序就只能用堆来玩了You are given two integer arraysnums1andnums2sorted inascending orderand an integerk.Define a pair(u, v)which consists of one element from the first array and one element from the second array.Returnthekpairs(u1, v1), (u2, v2), ..., (uk, vk)with the smallest sums.Example 1:Input:nums1 [1,7,11], nums2 [2,4,6], k 3Output:[[1,2],[1,4],[1,6]]Explanation: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:Input:nums1 [1,1,2], nums2 [1,2,3], k 2Output:[[1,1],[1,1]]Explanation: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:Input:nums1 [1,2], nums2 [3], k 3Output:[[1,3],[2,3]]Explanation:All possible pairs are returned from the sequence: [1,3],[2,3]Constraints:1 nums1.length, nums2.length 105-109 nums1[i], nums2[i] 109nums1andnums2both are sorted inascending order.1 k 1000from typing import List import heapq class Solution: def kSmallestPairs(self, nums1: List[int], nums2: List[int], k: int) - List[List[int]]: l1, l2 len(nums1), len(nums2) hq,res [(nums1[0]nums2[0],0,0)],[] while (hq and len(res) k): csum,i,j heapq.heappop(hq) res.append([nums1[i],nums2[j]]) if (j1l2): heapq.heappush(hq,(nums1[i]nums2[j1],i,j1)) #列维度扩张由j说了算只有列是0的时候考虑一下行维度的扩张也控制了优先级 if j 0 and i1l1: heapq.heappush(hq,(nums1[i1]nums2[j],i1,j)) return res s Solution() print(s.kSmallestPairs(nums1 [1,2], nums2 [3], k 3)) print(s.kSmallestPairs(nums1 [1,1,2], nums2 [1,2,3], k 2)) print(s.kSmallestPairs(nums1 [1,7,11], nums2 [2,4,6], k 3)) #expected: [[0, -3], [0, -3], [0, -3], [0, -3], [0, -3], [0, 22], [0, 22], [0, 22], [0, 22], [0, 22], [0, 35], [0, 35], [0, 35], [0, 35], [0, 35], [0, 56], [0, 56], [0, 56], [0, 56], [0, 56], [0, 76], [0, 76]] # [[0, -3], [0, 22], [0, 35], [0, 56], [0, 76], [0, -3], [0, 22], [0, 35], [0, 56], [0, 76], [0, -3], [0, 22], [0, 35], [0, 56], [0, 76], [0, -3], [0, 22], [0, 35], [0, 56], [0, 76], [0, -3], [0, 22]] # [[0, -3], [0, -3], [0, -3], [0, -3], [0, -3], [0, 22], [0, 22], [0, 22], [0, 22], [0, 22], [0, 35], [0, 35], [0, 35], [0, 35], [0, 35], [0, 56], [0, 56], [0, 56], [0, 56], [0, 56], [0, 76], [0, 76]] print(s.kSmallestPairs([0,0,0,0,0],[-3,22,35,56,76],22))------------------------------------------------又发现一道钓鱼问题有n个湖在一条路上每个湖产量不一样A[n]均为正整数。​每个湖被钓1个小时之后产量会减1再被钓1小时后产量再减1没被钓不降低产量。​有k个小时求最大钓鱼量:解答这个题也很容易想到用堆的思路但是比较好的思路是假设产量超过x的湖才会钓鱼然后二分就可以得到O(n)复杂度解法。------------------------------------------------一组排序质数任选两个组成真分数求所有可能中第k小。请给出复杂度最小的做法class Solution: def count_lower(self, arr, target, n): i, res, p, q 0, 0, arr[0], arr[n - 1] for j in range(1, n): while (i j and arr[i] target * arr[j]): i 1 res i if (i 0 and arr[i - 1] * q p * arr[j]): p, q arr[i - 1], arr[j] return res, p, q def kthSmallest(self, arr, k): n len(arr) total n * (n - 1) // 2 if (k 1 or k total): raise ValueError(fk{k} out of range [1, {total}]) left, right, ans 0.0, 1.0, [arr[0], arr[n - 1]] while (right - left 1e-9): target (left right) / 2 lower, p, q self.count_lower(arr, target, n) if (lower k): left target else: right target ans [p, q] return ans

相关文章:

杨氏矩阵找第N大(小)的O(N)线性算法 LeetCode 378. Kth Smallest Element in a Sorted Matrix 373. Find K Pairs 钓鱼问题

杨氏矩阵&#xff1a;一个N*N的矩阵&#xff0c;它的每行每列都单调递增(或者宽松一些,单调不减)&#xff0c;即a[i][j]<a[i1][j], a[i][j]<a[i][j1]。遇到的两道面试题&#xff1a; 1. 输出杨氏矩阵中最小的N个数。 2. 两个升序数组A和B&#xff0c;长度都是N。从两个数…...

我用AI替换了高级工程师,结果...

周二下午 2:47&#xff0c;我们的 CFO 在 Slack 上发了一条消息。 “你团队的年薪是 120 万美元。我们能谈谈优化吗&#xff1f;” 我知道要发生什么了。我们刚刚完成了 A 轮融资。风投想要"运营效率"。翻译&#xff1a;削减成本、更快交付、展示增长。 我们的高级…...

【等保合集】800余份等保三级、等保2.0、等保二级、等保测评作业指导、全套信息安全管理体系文件、标准规范方案报告合集(PPT+WORD+PDF)

等保2.0以GB/T 22239-2019为核心&#xff0c;二级&#xff08;指导保护级&#xff09;与三级&#xff08;监督保护级&#xff09;在身份认证、数据加密、备份恢复及管理制度上差异显著。测评作业指导书依据GB/T 28448编制&#xff0c;覆盖十大安全类&#xff1b;信息安全管理体…...

MBTI职业性格测试

...

【GIS操作指南】ArcMap界面坐标单位一键切换:从平面到经纬度的实战设置

1. 为什么需要切换坐标单位&#xff1f; 刚接触ArcMap的朋友可能会发现&#xff0c;软件右下角默认显示的坐标单位往往是米或千米这类平面单位。但在处理带有地理坐标的数据时&#xff0c;比如气象数据、GPS轨迹或者行政区划边界&#xff0c;我们更习惯使用经纬度来定位。这就好…...

手把手教你为RK3568(arm64)交叉编译BlueZ:利用Buildroot已有环境快速出包

手把手教你为RK3568&#xff08;arm64&#xff09;交叉编译BlueZ&#xff1a;利用Buildroot已有环境快速出包 在嵌入式Linux开发中&#xff0c;蓝牙协议栈BlueZ的交叉编译一直是让开发者头疼的问题。特别是当目标平台采用arm64架构时&#xff0c;依赖库的复杂性和工具链的配置难…...

从零搭建PX4无人机仿真环境:Gazebo场景构建与Offboard模式初探

1. 环境准备&#xff1a;从零搭建PX4开发基础 第一次接触PX4无人机开发的朋友&#xff0c;往往会被复杂的工具链吓到。其实只要跟着正确的步骤走&#xff0c;半小时内就能搭建好完整的仿真环境。我用的是一台装好Ubuntu 20.04的笔记本&#xff0c;建议至少预留30GB磁盘空间。 关…...

海康工业相机——Python二次开发实战:构建实时条形码识别系统

1. 环境准备与硬件选型 第一次接触海康工业相机时&#xff0c;我被它金属外壳下的精密光学元件震撼到了。这种工业级设备和我们平时用的消费级摄像头完全不同&#xff0c;它的稳定性、帧率和图像质量完全是为生产线环境设计的。如果你手头正好有台海康相机&#xff0c;跟着我的…...

别再只盯着输入了!时间序列预测中,被忽视的‘标签自相关’问题与FreDF解法

时间序列预测的盲区&#xff1a;标签自相关性如何悄悄破坏你的模型精度 想象一下&#xff0c;你花费数周时间调整模型架构、优化超参数&#xff0c;甚至尝试了最新的Transformer变体&#xff0c;但预测结果始终差强人意。问题可能并不出在你精心设计的输入特征工程上&#xff0…...

ESP32定时器深度解析:从基础API到低功耗场景实战

1. ESP32定时器基础入门 第一次接触ESP32的硬件定时器时&#xff0c;我被它强大的功能和灵活的配置选项深深吸引。相比常见的软件定时器&#xff0c;ESP32的硬件定时器能提供微秒级精度和64位计时范围&#xff0c;这在物联网设备开发中简直是神器。 举个生活中的例子&#xff0…...

Pyinstaller:打包Python文件成exe可执行文件

1、pyinstaller安装pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple2、打包单个文件如果所有代码是写在一个.py文件里的&#xff0c;可以尝试使用这种方式pyinstaller -F filesname.py成功运行后会在桌面生成三个文件&#xff1a;可执行文件.exe就在dist…...

从CH341驱动入手,彻底搞懂Linux USB转串口驱动的三层架构(Serial/TTY/USB)

从CH341驱动剖析Linux USB转串口的三层架构设计 在嵌入式开发和工业控制领域&#xff0c;USB转串口设备扮演着关键角色。当我们为一块开发板编写底层驱动&#xff0c;或是调试一个突然"失联"的串口设备时&#xff0c;真正考验开发者功力的不是简单的驱动加载&#xf…...

佛山高铁隧道灯生产厂家选型实操攻略,4步规避采购风险

高铁隧道工程中&#xff0c;灯具选型直接影响工程质量与后期运维成本&#xff0c;佛山作为照明产业带&#xff0c;高铁隧道灯生产厂家数量众多&#xff0c;如何科学筛选成为工程采购的关键。本文结合实操经验&#xff0c;整理详细选型步骤&#xff0c;助力采购避坑。首先跟大家…...

避坑指南:AUTOSAR FlashDriver操作DFlash模拟EEPROM时,你最容易忽略的5个细节

AUTOSAR实战&#xff1a;DFlash模拟EEPROM的五大隐蔽陷阱与工程化解决方案 在汽车电子控制单元&#xff08;ECU&#xff09;开发中&#xff0c;使用DFlash模拟EEPROM存储NvM数据已成为行业普遍选择——既能降低硬件成本&#xff0c;又能满足AUTOSAR标准的数据存储需求。但许多工…...

用快马平台快速构建密码强度检测器,十分钟完成网络安全原型验证

今天想和大家分享一个快速验证网络安全功能的实战案例——用InsCode(快马)平台十分钟搭建密码强度检测器。作为经常需要处理用户注册功能的开发者&#xff0c;密码强度验证是每个项目都绕不开的基础安全需求&#xff0c;但传统开发流程中&#xff0c;光是搭环境、写基础代码就可…...

Claude Code 最佳实践:构建可验证、可治理、可扩展的生产级分布式系统

Claude Code 最佳实践:构建可验证、可治理、可扩展的生产级分布式系统 在很多团队的第一印象里,Claude Code 只是“更强一点的命令行编码助手”。但一旦进入中大型研发场景,你很快会发现,真正决定它价值上限的,不是单次补全能力,而是它是否能够被纳入一套可验证、可治理…...

Unpoly表单处理终极教程:实时验证与乐观渲染实践

Unpoly表单处理终极教程&#xff1a;实时验证与乐观渲染实践 【免费下载链接】unpoly Progressive enhancement for HTML 项目地址: https://gitcode.com/gh_mirrors/un/unpoly Unpoly是一个强大的渐进式增强HTML框架&#xff0c;能够显著提升Web应用的表单处理体验。通…...

如何用klein.php构建RESTful API:10个实用技巧与最佳实践

如何用klein.php构建RESTful API&#xff1a;10个实用技巧与最佳实践 【免费下载链接】klein.php A fast & flexible router 项目地址: https://gitcode.com/gh_mirrors/kl/klein.php klein.php是一款轻量级且高性能的PHP路由库&#xff0c;专为构建快速灵活的Web应…...

gdocs2md安装与配置完全教程:如何正确设置Google Apps Script

gdocs2md安装与配置完全教程&#xff1a;如何正确设置Google Apps Script 【免费下载链接】gdocs2md Convert a Google Drive Document to the Markdown format, suitable for publishing. 项目地址: https://gitcode.com/gh_mirrors/gd/gdocs2md gdocs2md是一款简单实用…...

一人干出3人活!当贝Molili在混沌学园教你用好OpenClaw

如果说2025年是AI大模型的内卷之年&#xff0c;2026年则是AI Agent(智能体)规模化落地的元年。3月29日&#xff0c;当贝Molili产品负责人唐涛受邀登上国内创新标杆混沌学园的讲坛&#xff0c;以《用OpenClaw打造7x24小时个人分身&#xff0c;一人团队如何干出3人产出》为主题&a…...

bilibili-parse:让B站视频解析变得简单高效的PHP工具

bilibili-parse&#xff1a;让B站视频解析变得简单高效的PHP工具 【免费下载链接】bilibili-parse bilibili Video API 项目地址: https://gitcode.com/gh_mirrors/bi/bilibili-parse 价值定位&#xff1a;为什么选择bilibili-parse 当你需要在自己的项目中集成B站视频…...

基于深度学习的手把手学习 YOLOv8-Pose 关键点检测实战:杂草根茎关键点标注与训练全流程指南

YOLOv8-Pose 关键点检测实战&#xff1a;杂草根茎关键点标注与训练全流程指南 作者&#xff1a;张教授&#xff08;计算机视觉与农业AI实验室主任&#xff09; 引言在精准农业和智能除草领域&#xff0c;杂草根茎关键点检测技术具有重要意义。传统YOLO系列主要关注目标检测&…...

并发编程模式(如生产者-消费者、任务分区、发布-订阅等)可以帮助我们更好地组织多线程代码,提高可维护性、性能和健壮性

基于之前的线程同步优化代码,我将进一步引入并发编程模式,以更结构化和可扩展的方式优化加热控制逻辑。并发编程模式(如生产者-消费者、任务分区、发布-订阅等)可以帮助我们更好地组织多线程代码,提高可维护性、性能和健壮性。 在加热控制场景中,适合的模式包括任务分区…...

SuperDuperDB事件驱动架构:构建实时AI应用的全新方式

SuperDuperDB事件驱动架构&#xff1a;构建实时AI应用的全新方式 【免费下载链接】superduperdb Superduper: End-to-end framework for building custom AI applications and agents. 项目地址: https://gitcode.com/gh_mirrors/su/superduperdb SuperDuperDB是一个端到…...

开箱即用!Qwen3-VL-8B AI聊天系统一键启动,小白也能玩转

开箱即用&#xff01;Qwen3-VL-8B AI聊天系统一键启动&#xff0c;小白也能玩转 1. 项目概览&#xff1a;你的智能聊天助手 想象一下&#xff0c;你刚拿到一个功能强大的AI聊天系统&#xff0c;不需要任何复杂配置&#xff0c;就像打开一个新买的智能音箱一样简单。这就是Qwe…...

uosc性能优化实战:解决UI卡顿与渲染延迟问题终极指南

uosc性能优化实战&#xff1a;解决UI卡顿与渲染延迟问题终极指南 【免费下载链接】uosc Feature-rich minimalist proximity-based UI for MPV player. 项目地址: https://gitcode.com/gh_mirrors/uo/uosc uosc是一款功能丰富的极简主义基于接近度的MPV播放器用户界面&a…...

为什么说Rust是对自闭症谱系人士友好的编程语言?

程序员圈子里&#xff0c;Rust常常以学习路线陡峭而闻名。就我自己的个人理解来说&#xff0c;之所以说它“学习路线陡峭”&#xff0c;很大程度上都来源于以下三点&#xff1a;Rust有很多语法糖&#xff0c;而且官方把这些语法糖给设置成了默认的最佳实现的语法&#xff0c;还…...

突破限速!多平台适配的网盘直链下载工具:3步解锁高速下载体验

突破限速&#xff01;多平台适配的网盘直链下载工具&#xff1a;3步解锁高速下载体验 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中…...

三步打造完美Jellyfin番剧库:Bangumi插件实战指南

三步打造完美Jellyfin番剧库&#xff1a;Bangumi插件实战指南 【免费下载链接】jellyfin-plugin-bangumi bgm.tv plugin for jellyfin 项目地址: https://gitcode.com/gh_mirrors/je/jellyfin-plugin-bangumi 你是否曾为Jellyfin中的动漫收藏而烦恼&#xff1f;看着那些…...

批量新建文件夹工具:两种模式与重名策略怎么选

在 Windows 上做项目资料归档、测试用例目录、素材库初始化时&#xff0c;“先把一套文件夹结构建出来”是很常见的动作。手动右键新建很容易漏、很容易层级点错&#xff0c;也很难复用。这里记录一下【批量新建文件夹工具】的用法要点&#xff08;只讲界面能力与参数选择&…...