(说明:本博客中的题目、题目详细说明及参考代码均摘自 “何海涛《剑指Offer:名企面试官精讲典型编程题》2012年”)

题目

  在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断是否含有该整数。

  进一步的详细说明:

  下图中的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字 7,则返回 true;如果查找数字 5,由于数组不含有该数字,则返回 false。

算法设计思想

  对于类似上图中的二维数组,选择从右上方(数字 9)或 左下方(数字 6)开始遍历,这样可以保证向单一方向缩小搜索范围;而从左上方(数字 1)或右下方(数字 15)开始遍历,可以朝两个方向进行进一步搜索,从而导致无法缩小范围。

以查找数字 5 为例,
  若从左下方(数字 6)开始遍历,则由于数字 5 < 6 ,根据二维数组沿行从左到右递增,沿列从上到下递增,数字 5 可能位于数字 6 的上方或左侧,而数字 6 的左侧无元素,因此数字 5 只能位于数字 6 的上方,从而缩小了搜索范围;
  若从左上方(数字 1)开始遍历,则由于数字 5 > 1,根据二维数组沿行从左到右递增,沿列从上到下递增,数字 5 可能位于数字 1 的下方或右侧,而数字 1的下方和右侧均有元素,因此无法缩小搜索范围。

  以上说明,找到一个好的起点很重要,其会直接影响算法的可行性。

C++ 实现

#include <iostream>

using namespace std;

// Try to find 'target' from 'matrix' with 'rows' rows and 'cols' columns,
// If found, return true; else return false
bool Find(int* matrix, int rows, int cols, int target)
{
bool found = false; if (!matrix || rows < || cols < ) // 易漏点
return found;
int i = ;
int j = cols-; // Note: the index of the last element in each row is cols-1. // 易错点
while ((i < rows) && (j >= ))
{
int current = *(matrix+i*cols+j); if (target < current)
j--;
else if (target > current)
i++;
else { // target == current
found = true;
break;
}
} return found;
} // Display the result whether the target is found.
void display(int* matrix, int rows, int cols, int target)
{
cout << "Target " << target << " is ";
if (Find(matrix, rows, cols, target))
cout << "";
else
cout << "not ";
cout << "found." << endl;
} void unitest()
{
int mat[] = {, , , ,
, , , ,
, , , ,
, , , };
// Try to find digits 7 and 5, then display the result
display(mat, , , );
display(mat, , , );
} int main()
{
unitest();
return ;
}

Python 实现

#!/usr/bin/python
# -*- coding: utf8 -*- # Try to find 'target' from 'matrix' with 'rows' rows and 'cols' columns,
# If found, return true; else return false
def find_target(matrix, rows, cols, target):
found = False
if not matrix or rows < 0 or cols < 0: # 易漏点
return found
i, j = 0, cols-1 # 易错点
while i < rows and j >= 0:
current = matrix[i*cols+j]
if target < current:
j -= 1
elif target > current:
i += 1
else: # target == current
found = True
break return found def unitest():
mat = [1, 2, 8, 9,
2, 4, 9, 12,
4, 7, 10, 13,
6, 8, 11, 15]
# Try to find digits 7 and 5, then display the result
for target in [7, 5]:
print "Target %d is %s found." % (target, "" if find_target(mat, 4, 4, target) else "not") if __name__ == "__main__":
unitest()

参考代码

1. targetver.h

#pragma once

// The following macros define the minimum required platform.  The minimum required platform
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
// your application. The macros work by enabling all features available on platform versions up to and
// including the version specified. // Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
#endif

2. stdafx.h

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
// #pragma once #include "targetver.h" #include <stdio.h>
#include <tchar.h> // TODO: reference additional headers your program requires here

3. stdafx.cpp

// stdafx.cpp : source file that includes just the standard includes
// FindInPartiallySortedMatrix.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information #include "stdafx.h" // TODO: reference any additional headers you need in STDAFX.H
// and not in this file

4. FindInPartiallySortedMatrix.cpp

// FindInPartiallySortedMatrix.cpp : Defines the entry point for the console application.
// // 《剑指Offer——名企面试官精讲典型编程题》代码
// 著作权所有者:何海涛 #include "stdafx.h" // 二维数组matrix中,每一行都从左到右递增排序,
// 每一列都从上到下递增排序
bool Find(int* matrix, int rows, int columns, int number)
{
bool found = false; if(matrix != NULL && rows > && columns > )
{
int row = ;
int column = columns - ;
while(row < rows && column >=)
{
if(matrix[row * columns + column] == number)
{
found = true;
break;
}
else if(matrix[row * columns + column] > number)
-- column;
else
++ row;
}
} return found;
} // ====================测试代码====================
void Test(char* testName, int* matrix, int rows, int columns, int number, bool expected)
{
if(testName != NULL)
printf("%s begins: ", testName); bool result = Find(matrix, rows, columns, number);
if(result == expected)
printf("Passed.\n");
else
printf("Failed.\n");
} // 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的数在数组中
void Test1()
{
int matrix[][] = {{, , , }, {, , , }, {, , , }, {, , , }};
Test("Test1", (int*)matrix, , , , true);
} // 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的数不在数组中
void Test2()
{
int matrix[][] = {{, , , }, {, , , }, {, , , }, {, , , }};
Test("Test2", (int*)matrix, , , , false);
} // 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的数是数组中最小的数字
void Test3()
{
int matrix[][] = {{, , , }, {, , , }, {, , , }, {, , , }};
Test("Test3", (int*)matrix, , , , true);
} // 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的数是数组中最大的数字
void Test4()
{
int matrix[][] = {{, , , }, {, , , }, {, , , }, {, , , }};
Test("Test4", (int*)matrix, , , , true);
} // 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的数比数组中最小的数字还小
void Test5()
{
int matrix[][] = {{, , , }, {, , , }, {, , , }, {, , , }};
Test("Test5", (int*)matrix, , , , false);
} // 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的数比数组中最大的数字还大
void Test6()
{
int matrix[][] = {{, , , }, {, , , }, {, , , }, {, , , }};
Test("Test6", (int*)matrix, , , , false);
} // 鲁棒性测试,输入空指针
void Test7()
{
Test("Test7", NULL, , , , false);
} int _tmain(int argc, _TCHAR* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7(); return ;
}

5. 项目 03_FindInPartiallySortedMatrix 下载

百度网盘: 03_FindInPartiallySortedMatrix.zip

参考资料

[1]  何海涛. 剑指 Offer:名企面试官精讲典型编程题 [M]. 北京:电子工业出版社,2012. 38-41.

二维数组中的查找(C++和Python实现)的更多相关文章

  1. 剑指Offer面试题:2.二维数组中的查找

    一.题目:二维数组中的查找 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. ...

  2. 剑指Offer:面试题3——二维数组中的查找(java实现)

    问题描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路:取数组中的元素与 ...

  3. 【面试题003】c数组做为参数退化的问题,二维数组中的查找

    [面试题003]c数组做为参数退化的问题,二维数组中的查找  一,c数组做为参数退化的问题 1.c/c++没有记录数组的大小,因此用指针访问数组中的元素的时候,我们要确保没有超过数组的边界, 通过下面 ...

  4. 九度OJ 题目1384:二维数组中的查找

    /********************************* * 日期:2013-10-11 * 作者:SJF0115 * 题号: 九度OJ 题目1384:二维数组中的查找 * 来源:http ...

  5. 《剑指Offer》面试题-二维数组中的查找

    题目1384:二维数组中的查找 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:7318 解决:1418 题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到 ...

  6. 《剑指offer》— JavaScript(1)二维数组中的查找

    二维数组中的查找 题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. ** ...

  7. 剑指offfer:二维数组中的查找

    题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成这样一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 例如: 1    2  ...

  8. C#版 - 小红书后台开发面试题: 二维数组中的查找

    二维数组中的查找 热度指数:24274 时间限制:1秒 空间限制:32768K 本题知识点: 查找 ​ 在线提交网址: http://www.nowcoder.com/practice/abc3fe2 ...

  9. 二维数组中的查找问题--剑指offer面试题3

    题目:在一个二维数组中,对每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. // 二维数组中的查找 ...

  10. 《剑指offer》 二维数组中的查找

    本题目是<剑指offer>中的题目 二维数组中的查找 题目: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个 ...

随机推荐

  1. Android的崩溃类型总结

    看了篇腾讯的沙龙分享,觉得很不错,在这里分享给大家 crash的大致划分:

  2. ionic3 pop到指定页面

    this.navCtrl.getViews().forEach(element => { if(element.name == 'JiecheHomePage'){ this.navCtrl.p ...

  3. Android 开发 命名规范(基础回顾)

    标识符命名法标识符命名法最要有四种: 1 驼峰(Camel)命名法:又称小驼峰命名法,除首单词外,其余所有单词的第一个字母大写. 2 帕斯卡(pascal)命名法:又称大驼峰命名法,所有单词的第一个字 ...

  4. 深入java虚拟机学习 -- 类的卸载

    类的生命周期 在开始本节之前让我们再来回顾下类的生命周期 没看过前6个过程的同学建议从头看下<深入java虚拟机学习 -- 类的加载机制>,这里就不再过多介绍了,着重说下类的卸载 类的卸载 ...

  5. js模块加载框架 sea.js学习笔记

    seajs实现了JavaScript 的 模块开发及按模块加载.用来解决繁琐的js命名冲突,文件依赖等问题,其主要目的是令JavaScript开发模块化并可以轻松愉悦进行加载. 官方文档:http:/ ...

  6. MySql的用户权限

    用户管理 MySQL数据库中的表与其他任何关系表没有区别,都可以通过典型的SQL命令修改其结构和数据.可以使用GRANT和REVOKE命令.通过这些命令,可以创建和禁用用户,可以在线授予和撤回用户访问 ...

  7. React项目的打包

    1.create-react-app 来自Facebook官方的零配置命令行工具.create-react-app是来自于Facebook出品的零配置命令行工具,能够帮你自动创建基于Webpack+E ...

  8. 从零实现一个简易的jQuery框架之二—核心思路详解

    如何读源码 jQuery整体框架甚是复杂,也不易读懂.但是若想要在前端的路上走得更远.更好,研究分析前端的框架无疑是进阶路上必经之路.但是庞大的源码往往让我们不知道从何处开始下手.在很长的时间里我也被 ...

  9. hexo+github搭建博客跳坑

    hexo+GitHub搭建博客过程中,hexo安装成功,可以启动和运行,但是访问localhost:4000却无法访问,弄了半天,最后发现是福昕阅读器占用了4000端口 解决办法: 采用命令hexo ...

  10. 常用软件下载开发环境七牛镜像Java、Node、Mongo

    [jdk1.8] Linux:http://soft.yzeng.cc/jdk18/jdk-8u202-linux-x64.tar.gz Windows:http://soft.yzeng.cc/jd ...