没有合适的资源?快使用搜索试试~ 我知道了~
首页剑指Offer Java版:二维数组查找与数组优化详解
剑指Offer Java版:二维数组查找与数组优化详解
5星 · 超过95%的资源 需积分: 10 21 下载量 55 浏览量
更新于2024-07-20
2
收藏 1009KB PDF 举报
"剑指Offer精解(Java版)"是由崔洪振整理的一套针对Java程序员的面试题解答书籍。本书主要围绕《剑指Offer》系列的Java版习题进行深入解析,旨在帮助读者提升编程技巧和解决实际面试中可能出现的算法问题。章节Q3涉及的是二维数组中的查找算法,这是一个经典的数据结构和算法应用问题。 在这个问题中,给出的场景是处理一个特殊的二维数组,数组的特点是每行和每列都按照升序排列。函数`findNum`的目的是在这样的数组中查找一个给定的整数`number`是否存在。函数首先检查输入的二维数组是否有效,即数组是否为`null`。然后,它从左上角的元素开始,通过逐行或逐列缩小搜索范围的方式进行查找: 1. 如果左上角的元素恰好等于`number`,则直接返回`true`,表示找到了目标数。 2. 如果左上角的元素小于`number`,则删除一行(将`cow`加1,跳过这一行),因为数组的递增性保证了大于`number`的元素都在其右侧。 3. 同理,如果当前列的元素小于`number`,则删除一列(将`column`减1,跳过这一列),因为数组的递增性保证了大于`number`的元素都在其下方。 这个算法的时间复杂度是O(m+n),其中m是行数,n是列数。因为最坏情况下需要遍历整个二维数组。通过这种方法,可以有效地在有序的二维数组中查找指定的数值,展示了数组和搜索算法的巧妙结合。 学习这道题,不仅可以加深对Java数组操作的理解,还能提高查找算法的实战能力,对面试中的数据结构和算法问题有很好的准备。阅读这本书籍,对于提高编程面试的成功率非常有帮助。
资源详情
资源推荐
剑指 Offer 习题答案(Java 版)崔洪振
第 16 页
剑指 Offer 习题答案(Java 版)崔洪振
Q8:旋转数组的最小数字
import java.util.Arrays;
public class Q8 {
/**
* 题目:旋转数组的最小数字
* 要求:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
* 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。
* 例如:数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.
*/
public static void main(String[] args) {
Q8 q8 = new Q8();
//int[] data = {3,4,5,1,2};
int[] data = {1,0,1,1,1};
System.out.println("排序前的数组是:\n"+Arrays.toString(data));
//调用方法Min()查找,并输出
System.out.println("最小元素是:\n"+q8.Min(data));
}
public static int Min(int[] data){
//判断数组是否合法
if(data == null || data.length <=0){
return 0;
}
int index1 = 0;
int index2 = data.length-1;
int indexMid = 0;
//只要前边的元素大于后边的元素就执行循环
while(data[index1] >= data[index2]){
//索引值相邻时,将index2的值赋给indexMid
if(index2 - index1 == 1){
indexMid = index2;
break;
}
//中间索引值的变化
indexMid = (index1 + index2)/2;
//特殊情况的处理
if(data[index1] == data[index2] && data[index1] ==
data[indexMid]){
return MidOrder(data, index1, index2);
}
//中间值大于前边的元素,说明最小值在后边,则将中间值赋给index1
if(data[indexMid] >= data[index1]){
index1 = indexMid;
剑指 Offer 习题答案(Java 版)崔洪振
第 17 页
剑指 Offer 习题答案(Java 版)崔洪振
}
//中间值小于后边的元素,说明最小值是中间值或中间值右边的元素,则将中间
值赋给index2
else if(data[indexMid] <= data[index2]) {
index2 = indexMid;
}
}
return data[indexMid];
}
//特殊情况处理:如果index1、index2和indexmid的值相同则使用顺序查找
public static int MidOrder(int[] data, int index1, int index2){
int result = data[index1];
for(int i = index1; i <= index2; i++){
if(result > data[i])
result = data[i];
}
return result;
}
}
思路整理:
1、 了解什么是旋转数组;
2、 怎样寻找最小值(考查二分查找);
3、 设置索引值的技巧,和命名方法;
4、 考虑特殊情况的处理。
剑指 Offer 习题答案(Java 版)崔洪振
第 18 页
剑指 Offer 习题答案(Java 版)崔洪振
Q9:斐波那契数列
public class Q9 {
/**
* 题目:斐波那契数列
* 题目说明:写一个函数,输入n,求斐波那契数列的第n项。斐波那契数列的定义如下:
* f(n)=0;n=0
* f(n)=1;n=1
* f(n)=f(n-1)+f(n-2);n>1
* 解题思路:解决该类问题可以从两个方向进行:1)利用递归实现;但是这种方法当
输入数值较大时,时间效率较低;其时间随着n呈指数增加。
* 2)利用for循环来实现,时间复杂度为O(n)级别。
*/
public static void main(String[] args) {
Q9 test=new Q9();
System.out.println(test.fibonacci1(10));
System.out.println(test.fibonacci2(10));
}
//利用递归实现
public long fibonacci1(int n){
if(n<=0){
return 0;
}
if(n==1){
return 1;
}
return fibonacci1(n-1)+fibonacci1(n-2);
}
//利用for循环实现
public long fibonacci2(int n){
int numberMin=0;
int numberMax=1;
int result=0;
if(n==numberMin){
return numberMin;
}
if(n==numberMax){
return numberMax;
}
//注意此处条件是从2开始的,包含n
for(int i=2; i<=n; i++){
/*
* 赋值过程规律:和=大数+小数;
* 小数=大数;
剑指 Offer 习题答案(Java 版)崔洪振
第 19 页
剑指 Offer 习题答案(Java 版)崔洪振
* 大数=和;
* */
result=numberMin+numberMax;
numberMin=numberMax;
numberMax=result;
}
return result;
}
}
剑指 Offer 习题答案(Java 版)崔洪振
第 20 页
剑指 Offer 习题答案(Java 版)崔洪振
Q10:二进制中 1 的个数
public class Q10 {
/**
* 题目:二进制中1的个数。
* 说明:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表
示成二进制是1001,有2位是1.因此如果输入9,该函数输出2.
* 思路:解决该问题主要是依靠两个方面的知识,一个是位移二进制,另一个是位与运
算。
* 解法一:通过普通的逐位右移实现。先判断整数二进制表示中最右边一位是不是1(通
过与运算判断),然后右移一位在判断。
* 解法二:(最优解法)把整数减1,然后和原数做与运算,会把整数右边的1变成0。一
个整数的二进制中有多少个1,就可以进行多少次这样的操作。
* 说明:所有方法的实现都是依靠移位运算实现的的,不是通过除以2来实现右移运算
的,因为除法的效率远远低于移位的效率。(实际编程中尽可能用移位运算代替乘除法)
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Q10 test=new Q10();
System.out.println(test.BinaryNumberOf11(9));
System.out.println(test.BinaryNumberOf12(9));
}
//解法一:这种方法容易出现死循环。
public int BinaryNumberOf11(int n){
int count=0;
while(n!=0){
if((n&1)==1){
count++;
}
n=n>>1;
}
return count;
}
//解法二:最优解法
public int BinaryNumberOf12(int n){
int count=0;
while(n!=0){
count++;
n=(n-1)&n;
}
return count;
}
}
剩余139页未读,继续阅读
振哥在,世界充满爱!
- 粉丝: 2211
- 资源: 23
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- zlib-1.2.12压缩包解析与技术要点
- 微信小程序滑动选项卡源码模版发布
- Unity虚拟人物唇同步插件Oculus Lipsync介绍
- Nginx 1.18.0版本WinSW自动安装与管理指南
- Java Swing和JDBC实现的ATM系统源码解析
- 掌握Spark Streaming与Maven集成的分布式大数据处理
- 深入学习推荐系统:教程、案例与项目实践
- Web开发者必备的取色工具软件介绍
- C语言实现李春葆数据结构实验程序
- 超市管理系统开发:asp+SQL Server 2005实战
- Redis伪集群搭建教程与实践
- 掌握网络活动细节:Wireshark v3.6.3网络嗅探工具详解
- 全面掌握美赛:建模、分析与编程实现教程
- Java图书馆系统完整项目源码及SQL文件解析
- PCtoLCD2002软件:高效图片和字符取模转换
- Java开发的体育赛事在线购票系统源码分析
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功