《剑指Offer》- 面试题3
《剑指Offer——名企面试官精讲典型编程题》
面试题3:
二维数组元素从左到右、从上到下递增,输入一个二维数组和一个整数,
查找该整数。
自己的思路:有序条件下进行查找,当然最简单的是顺序查找(O(n))。但更好的方法如下:
1、二维数组第1和最后一个元素分别为A,B,同时为最小和最大,先判断输入整数的范围
在A~B之间,转到2;
2、按行分情况查找,每一行采用折半查找(O(logn))。
说明:函数返回true代表查找成功,查找位置用引用返回。
//《剑指Offer——名企面试官精讲典型编程题》
// 面试题3: #include "stdafx.h"
#include<iostream>
using namespace std; const int ROW = ;
const int COL = ; bool SearchDArray(int arr[][COL], int value, int& row, int& col);
int HalfSearch(int arr[][COL],int row, int value, int low, int high); int main(int argc, char* argv[])
{
int TwoDArray[ROW][COL] =
{
{,,,,},
{,,,,},
{,,,,},
{,,,,}
};
int row = ROW;
int column = COL;
bool FindOrNot = SearchDArray(TwoDArray,,row,column);
if(FindOrNot)
cout<<"TwoDArray["<<row<<"]["<<column<<"] "
<<"is the right location!"<<endl;
else
cout<<"Not Find!"<<endl;
return ;
} bool SearchDArray(int arr[][COL], int value, int& row, int& col)
{
//arr非空
if(arr == NULL || row <= 0 || col <= 0)
return false; //value值应在最大最小之间
if(value < arr[][] || value > arr[row-][col-])
return false; //按行折半查找
bool BeFind = false;
int valueloc;
for(int i=; i<row && !BeFind; i++)
{
if(arr[i][col-] >= value)
{
valueloc = HalfSearch(arr,i,value,,col-);
if(valueloc>=)
BeFind = true;
}
}
if(BeFind)
{
row = i-;
col = valueloc;
}
return BeFind; }
//折半查找
int HalfSearch(int arr[][COL],int row, int value, int low, int high)
{
int mid;
while(low <= high)
{
mid = (low+high)/;
if(arr[row][mid] < value)
low = mid+;
else if(arr[row][mid] > value)
high = mid-;
else
return mid;
}
if(low > high)
return -; }
1、折半查找是自己在学习完《数据结构》后,第一次编程实现,纠结于low<=high
记住:low==high时,也是需要比较的!!!
2、用引用返回位置,避免设置一个结构体。
3、二维数组当做函数参数时,形参为1. int arr[][col]; 2. int (*arr)[col],列不能少!
//按作者提供思路编写代码如下:
const int ROW = ;
const int COL = ; bool SearchDArray(int arr[][COL],int value, int& row, int& col); int main(int argc, char* argv[])
{
int TwoDArray[ROW][COL] =
{
{,,,,},
{,,,,},
{,,,,},
{,,,,}
};
int row = ROW;
int column = COL;
bool FindOrNot = SearchDArray(TwoDArray,,row,column);
if(FindOrNot)
cout<<"TwoDArray["<<row<<"]["<<column<<"] "
<<"is the right location!"<<endl;
else
cout<<"Not Find!"<<endl;
return ;
} bool SearchDArray(int arr[][COL],int value, int& row, int& col)
{
//右上角开始
int arrRow = ;
int arrCol = col-;
//分情况缩小二维数组
//缩小过程中判断找到情况
while(arrRow < ROW && arrCol >= )
{
if(arr[arrRow][arrCol] == value)
{
row = arrRow;
col = arrCol;
return true;
}
else if(arr[arrRow][arrCol] < value)
arrRow++;
else
arrCol--;
}
return false;
}
*/
折服于作者寻找规律的强悍,算法的精炼!
自己所想仅为:1、将value值同二维数组最后一列值比较,寻找value所在行;2、利用折半查找元素。
作者更加精炼:1、将value值同二维数组右上角元素比较,分三种情况考虑;
2、==,则找到; <value,则‘删掉’行; >value,则‘删掉’列;
3、直到二维矩阵‘空’。
总结:1、在这个过程中,自己首先想到顺序查找(适合所有情况),但面试题毕竟存在技巧,又因为数据的组织方式,所以想到分行比较,再折半查找。作者的思想 更进一步:不仅分行比较同时也分列比较。
2、想出作者的想法,前提是分析二维数组,想到利用‘四个角’!!该题可以利用‘右上角’和‘左下角’,另外,‘左上角’元素最小,‘右下角’元素最大!
3、鲁棒性测试时,直接输入NULL作为空指针代替二维数组!
4、循环和递归的区别及应用方面:之前老碰见递归的问题,递归可以用在解决同类但规模逐渐减小的问题上,自己有时候很容易同循环弄混。自己想想,递归应用应该比循环范围大。循环语句规模小于递归吧。(再体会。。。) 补充:刚分析了下,就比较次数而言,自己所写方法最坏情况下为 m+log(n),而作者方法最坏情况下为 n-1+m,这同顺序查找类似啊!但是,不管怎样,作者的思路很强大!
《剑指Offer》- 面试题3的更多相关文章
- 剑指Offer:面试题15——链表中倒数第k个结点(java实现)
问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...
- 剑指offer面试题3 二维数组中的查找(c)
剑指offer面试题三:
- 剑指Offer——笔试题+知识点总结
剑指Offer--笔试题+知识点总结 情景回顾 时间:2016.9.23 12:00-14:00 19:00-21:00 地点:山东省网络环境智能计算技术重点实验室 事件:笔试 注意事项:要有大局观, ...
- C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告
剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...
- C++版 - 剑指offer 面试题23:从上往下打印二叉树(二叉树的层次遍历BFS) 题解
剑指offer 面试题23:从上往下打印二叉树 参与人数:4853 时间限制:1秒 空间限制:32768K 提交网址: http://www.nowcoder.com/practice/7fe2 ...
- C++版 - 剑指offer 面试题39:判断平衡二叉树(LeetCode 110. Balanced Binary Tree) 题解
剑指offer 面试题39:判断平衡二叉树 提交网址: http://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId= ...
- Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)
剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...
- C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解
剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...
- C++版 - 剑指offer 面试题24:二叉搜索树BST的后序遍历序列(的判断) 题解
剑指offer 面试题24:二叉搜索树的后序遍历序列(的判断) 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true.否则返回false.假设输入的数组的任意两个 ...
- C++版 - 剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题,ZOJ 1088:System Overload类似)题解
剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题) 原书题目:0, 1, - , n-1 这n个数字排成一个圈圈,从数字0开始每次从圆圏里删除第m个数字.求出这个圈圈里剩下的最后一个数字 ...
随机推荐
- 理解C#系列 / 核心C# / 判断&循环&跳转
判断&循环&跳转 说明 本节写的是C#语言的控制程序流的语句,“控制程序流”就是控制程序运行流程的意思. 判断 很容易理解:如果……就…… if语句:测试特定条件是否满足,如果满足就执 ...
- 一步一步学习C++
根据<C++ primer>第五版 总结学习心得. 在实践中,不必全面地使用C++语言的各种特性,而应根据工程的实际情况,适当取舍(譬如动态类型信息,虚拟继承.异常等特性的使用,很值得商榷 ...
- BootStrap简介及应用要点
BootStrap简介 BootStrap是基于HTML.CSS和JavaScript的框架,使你只需要写简单的代码就可以很快的搭建一个还不错的前端框架,他是后端程序员的福音,使他们只需要专注业务逻辑 ...
- js设计模式(5)---外观模式
0.前言 早上好,今天天气不错,估计有35度吧,坐在空调室里相当惬意,那么酒足饭饱之后就应该干些正事了. 1. 为什么使用外观模式 外观模式提供了一个高层接口,封装一些复杂操作或繁琐行为,方便调用.门 ...
- silverlight webclient实现上传、下载、删除、读取文件
1.上传 private void Button_Click_1(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = ...
- 腾讯微博OAuth2.0 .NET4.0 SDK 发布以及网站腾讯微博登陆示例代码(原创)
1.使用简单方便,包含详细注释: 2.暂时只支持xml格式字符串的转换,建议接口使用xml参数:3.QweiboSDK.Controllers命名空间下已包含所有API接口:4.只需调用到Qweibo ...
- JAVA多线程学习1
一.进程与线程 线程是指进程内的一个执行单元(可理解为程序内的一条执行路径),也是进程内的可调度实体. 线程与进程的区别: 1.线程是进程的一个执行单元,一个进程可以拥有多个线程,线程之间共享进程的地 ...
- phpcms v9 源码解析(3)pc_base::creat_app()
69 return self::load_sys_classs('application'); 在前面我们已经知道了,这个load_sys_classs 静态方法,它加载了P ...
- FAN_int2ExcelColChar functions
static void FAN_int2ExcelColChar(Args _args) { Dialog dlg = new dialog("please enter int number ...
- java中print\println\printf的区别
print\println\printf的区别 print将它的参数显示在命令窗口,并将输出光标定位在所显示的最后一个字符之后. println 将它的参数显示在命令窗口,并在结尾加上换行符,将输出光 ...