常见面试题:二维递增数组的快速查找,复杂度(M+N-2),M,N分别为数组的行数和列数

本文主要是介绍常见面试题:二维递增数组的快速查找,复杂度(M+N-2),M,N分别为数组的行数和列数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:一个二维数组,按行按列都是递增的,要求程序在尽可能小的复杂度的情况下查找给定的元素。

例如:a[4][5]={
         {1, 3, 7, 11, 19},
         {2, 7, 10, 29, 30},
         {13, 28, 54, 69, 90},
         {46, 57, 78, 98, 101}
     }查找29,返回其下标(1,3)。

思路:需要充分利用数组的特点,按行按列都是递增的,这样才能减小复杂度。

下面就找一下特点喽,按行按列递增这是最明显的,还有隐含一点的就是,左上角和右下角分别是最小和最大的元素。恩,对的。哪还有呢?我们需要的是简便算法呀!继续看的话会发现,一列的最大元素在对应的最后一行,(废话),一行的最小一个在最左边。如果一个元素比一列的最下面一个元素还大的话,那它就一定不在这一列。诶,有点眉目了。如果要查找的元素比第一列的最下面一个元素还大的话,那它一定在之后的数组中。同理,目标如果比这个元素小的话,那它一定不在此行,且在上面的几行里。哈哈,数组又缩小了。然后,我们每次都能排除一行或一列,最难找的那个元素就是右上角的了。那它的复杂度是多少那?折线走过去,就是M-1+N-1,对啊,线性哎,不错1

//c语言
#include <stdio.h>
/*a是按行按列均递增的数组,该函数实现在数组中找出目标数据的下标,M和N表示数组的行数和列数*/
/*注:未考虑数组合法与否,返回的是数组的下标*/
int getIndexofIncArray(int *a, int M, int N, int target, int *x, int *y){int i=0, j = M-1, count;//找不到元素的话返回-1,找到的话返回0,i表示列*x = *y = -1;//初始化for(count=0; count<N+M;count++){printf("第%d次访问:%d\n",count, *(a + N*j + i));if(target == *(a + N*j + i)){*x = j;*y = i;return 0;}else	if(target > *(a + N*j + i)){//目标大于,右移if((i >= N) && (j < 0)){break;}else{i++;}}else{if((i >= N) && (j < 0)){break;}else{//目标小于,上移j--;}}}return -1;
}void  main(){int i, j;int *p1 = &i, *p2 = &j;int a[4][5]={{1, 3, 7, 11, 19},{2, 7, 10, 29, 30},{13, 28, 54, 69, 90},{46, 57, 78, 98, 101}};getIndexofIncArray(&a[0][0], 4, 5, 19, p1, p2);printf("%d, %d", i, j);getchar();
}


这篇关于常见面试题:二维递增数组的快速查找,复杂度(M+N-2),M,N分别为数组的行数和列数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1120476

相关文章

poj2576(二维背包)

题意:n个人分成两组,两组人数只差小于1 , 并且体重只差最小 对于人数要求恰好装满,对于体重要求尽量多,一开始没做出来,看了下解题,按照自己的感觉写,然后a了 状态转移方程:dp[i][j] = max(dp[i][j],dp[i-1][j-c[k]]+c[k]);其中i表示人数,j表示背包容量,k表示输入的体重的 代码如下: #include<iostream>#include<

hdu2159(二维背包)

这是我的第一道二维背包题,没想到自己一下子就A了,但是代码写的比较乱,下面的代码是我有重新修改的 状态转移:dp[i][j] = max(dp[i][j], dp[i-1][j-c[z]]+v[z]); 其中dp[i][j]表示,打了i个怪物,消耗j的耐力值,所得到的最大经验值 代码如下: #include<iostream>#include<algorithm>#include<

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

HDU 2159 二维完全背包

FATE 最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务。久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级。现在的问题是,xhd升掉最后一级还需n的经验值,xhd还留有m的忍耐度,每杀一个怪xhd会得到相应的经验,并减掉相应的忍耐度。当忍耐度降到0或者0以下时,xhd就不会玩这游戏。xhd还说了他最多只杀s只怪。请问他能

v0.dev快速开发

探索v0.dev:次世代开发者之利器 今之技艺日新月异,开发者之工具亦随之进步不辍。v0.dev者,新兴之开发者利器也,迅速引起众多开发者之瞩目。本文将引汝探究v0.dev之基本功能与优势,助汝速速上手,提升开发之效率。 何谓v0.dev? v0.dev者,现代化之开发者工具也,旨在简化并加速软件开发之过程。其集多种功能于一体,助开发者高效编写、测试及部署代码。无论汝为前端开发者、后端开发者

荣耀嵌入式面试题及参考答案

在项目中是否有使用过实时操作系统? 在我参与的项目中,有使用过实时操作系统。实时操作系统(RTOS)在对时间要求严格的应用场景中具有重要作用。我曾参与的一个工业自动化控制项目就采用了实时操作系统。在这个项目中,需要对多个传感器的数据进行实时采集和处理,并根据采集到的数据及时控制执行机构的动作。实时操作系统能够提供确定性的响应时间,确保关键任务在规定的时间内完成。 使用实时操作系统的

一些其他面试题

阿里二面:那你来说说定时任务?单机、分布式、调度框架下的定时任务实现是怎么完成的?懵了。。_哔哩哔哩_bilibili 1.定时算法 累加,第二层每一个格子是第一层的总时间400 ms= 20 * 20ms 2.MQ消息丢失 阿里二面:高并发场景下引进消息队列有什么问题?如何保证消息只被消费一次?真是捏了一把汗。。_哔哩哔哩_bilibili 发送消息失败