本篇介绍《剑指offer》第二版中的四个题目:找出数组中重复的数字、二维数组中的查找、替换字符串中的空格、计算斐波那契数列第n项。

这些题目并非严格按照书中的顺序展示的,而是按自己学习的顺序,每个题目包含了分析和代码,代码都是用Java语言编写的。

1、找出数组中重复的数字

题目:
        在一个长度为n的数组里,所有数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复,也不知道每个数字重复了几次,请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。
        解答:
        这里提供两种方式。
        第一种方式:本题所有数字都在0~n-1的范围内,如果数组中没有重复的数字,那么数组排序之后数字i与其下标i的值是一一对应的,即0-0、1-1、2-2……由于有重复数字,则排序后有些位置可能有多个数字,有些位置可能没有数字。
        这种方式的思路就是将数字i放到其下标i处,如果存在两个下标对应的数字相等,则说明有重复,该数字就是一个重复的数字。
        代码:

代码中尽管有两重循环,但每个数字最多只要交换两次就能找到它自己的位置,因此总的时间复杂度为O(n),同时空间复杂度为O(1),因此推荐此方法。
        第二种方式:用HashMap或ArrayList,都是先从第一个元素开始遍历数组,如果HashMap或ArrayList中不存在该元素,则将其放入,如果存在,则说明有重复。这种方式需要额外的空间,时间复杂度和空间复杂度都为O(n)。
        代码:

这里仅仅以HashMap为例,ArrayList与其类似,不再赘述。

      2、二维数组中的查找

题目:
        在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
        解答:
        这里提供4种类似的方式:可以先从二维数组右上角(第一行最后一列)的数字开始比较,如果它比要查找的数字小,则第一行所有数字都比它小,说明该数字不在第一行。然后比较第二行最后一列数字,如果比要查找的数字大,则说明在第二行,然后将第二行的数组按倒序的顺序逐个与其比较,直到找到为止。这种方式是从第一行往下逐行排除,找到目标数字所在的行以后,按倒序逐列排除。另外三种方式分别是从最后一行往上逐行排除,找到目标数字所在的行以后,按正序逐列排除;从最后一列往左逐列排除,找到目标数字所在的列以后,按正序逐行排除;从第一列往右逐列排除,找到目标数字所在的列以后,按倒序逐行排除。
        下面代码仅说明其中的两种按行排除的方式。
        代码:

      3、替换字符串中的空格

题目:
        请实现一个函数,把字符串中的每个空格替换成“%20”。例如,输入“We are happy.”,则输出“We%20are%20happy.”。
        解答:
        这里提供2种方式。
        第一种方式:先统计出原字符串中空格个数,并计算出替换之后字符串的长度,然后新建一个数组,使其长度等于替换之后字符串的长度,用于存放替换之后字符串。
        如果从前往后遍历字符串,碰到空格就替换,那么后面的字符可能会多次移动,总的时间复杂度为O(n²),效率不高。因此这里从后往前遍历原字符串,如果是非空格字符,就直接复制到新数组中(注意新数组也是从后往前放入字符);如果是空格,则按0、2、%的顺序放入新数组……直到遍历完字符串为止,这样就能保证每个元素只会移动一次,时间复杂度为O(n)。
        代码:

第二种方式:因为Java语言中String类型字符串是无法改变的,而StringBuilder和StringBuffer类型字符串是可以改变的,因此可以用这两个类型,通过append()方法拼接字符串。如果对线程安全有要求,则可以用StringBuffer,没要求可以用StringBuilder。以下以StringBuilder为例,StringBuffer与其类似。

 4、计算斐波那契数列第n项

题目:
        求斐波那契数列的第n项。写一个函数,输入n,求斐波那契数列的第n项。
        斐波那契数列定义如下:第1项F(1)=1,第2项F(2)=1,从第3项开始,每一项都等于前两项之和。前几项数字为:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377……
        解答:
        这里提供两种方式:非递归方式和递归方式。
        第一种方式,非递归方式(优先选择)。定义三个变量,分别存放前两项和第三项(当前项)的值,逐个计算斐波那契数列的每一项,直到第n项停止并返回。只有一个循环,时间复杂度为O(n)。
        代码:

第二种方式,递归方式。递归方式的代码很简洁,但仔细分析就会发现,递归方式计算的过程中会产生大量重复计算。比如想求f(10),得先计算出f(9)和f(8);同样想求出f(9),得先计算出f(8)和f(7);想求出f(8),得先计算出f(7)和f(6)……可以看到f(8)、f(7)等项都求了两次值。当n很大时,重复计算量会非常大,效率会很低,因此这种方式当n很小时还可以,很大时就不太适用了。所以优先推荐第一种方式。
        代码:

转载请注明出处 http://www.cnblogs.com/Y-oung/p/8858960.html

工作、学习、交流或有任何疑问,请联系邮箱:yy1340128046@163.com  微信:yy1340128046

剑指offer题目系列一的更多相关文章

  1. 剑指offer题目系列三(链表相关题目)

    本篇延续上一篇剑指offer题目系列二,介绍<剑指offer>第二版中的四个题目:O(1)时间内删除链表结点.链表中倒数第k个结点.反转链表.合并两个排序的链表.同样,这些题目并非严格按照 ...

  2. 剑指offer题目系列二

    本篇延续上一篇,介绍<剑指offer>第二版中的四个题目:从尾到头打印链表.用两个栈实现队列.旋转数组的最小数字.二进制中1的个数. 5.从尾到头打印链表 题目:输入一个链表的头结点,从尾 ...

  3. 代码题 — 剑指offer题目、总结

    剑指offer题目总结:  https://www.cnblogs.com/dingxiaoqiang/category/1117681.html 版权归作者所有,任何形式转载请联系作者.作者:马孔多 ...

  4. 再来五道剑指offer题目

    再来五道剑指offer题目 6.旋转数组的最小数字 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4, ...

  5. 剑指 Offer 题目汇总索引

    剑指 Offer 总目录:(共50道大题) 1. 赋值运算符函数(或应说复制拷贝函数问题) 2. 实现 Singleton 模式 (C#) 3.二维数组中的查找 4.替换空格              ...

  6. 牛客网上的剑指offer题目

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

  7. 剑指offer题目java实现

    Problem2:实现Singleton模式 题目描述:设计一个类,我们只能生成该类的一个实例 package Problem2; public class SingletonClass { /* * ...

  8. 【剑指Offer】剑指offer题目汇总

      本文为<剑指Offer>刷题笔记的总结篇,花了两个多月的时间,将牛客网上<剑指Offer>的66道题刷了一遍,以博客的形式整理了一遍,这66道题属于相对基础的算法题目,对于 ...

  9. 剑指offer自学系列(三)

    题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变,例如{5,1,4,2 ...

随机推荐

  1. # putty的使用和保存配置

    putty的使用和保存配置 之前使用的xshell5,但是突然之间需要我去注册,根本无法使用.在网上看到可以到官网申请家庭和学校版本,但是我的邮箱一直没有接收到邮件.于是我放弃xshell.就拿起了之 ...

  2. ANT 的Table表格样式修改方法

    注:(大家在给页面添加参数或者方法的时候,记得写上注释,方便别人查看) 1.表格行选中样式添加:(可以去beijing,精子库质控统计查看例子) (咱们以前页面上的表格都是在hover时显示选中效果, ...

  3. 如何用python语言撸出图表系统

    公司指标图表化显示,解决目前跟踪技术指标数据的各种不方便:于是话不多说,撸起袖子就是干: 1.挖掘需求和罗列功能点: a.图表显示技术指标数据. b.根据服务名和系统名查询对应的图表. c.根据日期区 ...

  4. 【BZOJ2510】弱题

    题目大意 有\(M\)个球,一开始每个球均有一个初始标号,标号范围为\(1-N\)且为整数,标号为i的球有\(a_i\)个,并保证\(\sum a_i=M\). 每次操作等概率取出一个球(即取出每个球 ...

  5. BZOJ3053:The Closest M Points(K-D Teee)

    Description The course of Software Design and Development Practice is objectionable. ZLC is facing a ...

  6. HDU 6070 线段树

    题意:求AC率,x/y 的最小值,x是区间数字的种类数,y是区间的长度. 分析: 二分答案比率.ans, 动态插入结点,一些区间的size会发生变化,是那些前面暂时没有新的结点的区间 size + 1 ...

  7. bpexpdate – 更改映像目录库中备份的截止日期以及介质目录库中介质的截止日期nbu

    1.根据bpdbjobs查找backupidbpdbjobs -jobid xxx -all_columns|grep backupid 2.查看数据保留时间[root@backup]# bpimag ...

  8. IO缓冲区

    标准IO提供的三种类型的缓冲模式: (1)按块缓存:在填满缓冲区后才进行实际的设备读写操作 (2)按行缓存:指在接收到换行符('\n’)之前,数据都是先缓存在缓冲区的 (3)不缓存:允许你直接读写设备 ...

  9. JS JavaScript中的this

    this是JavaScript语言中的一个关键字 它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用. function test() { this.x = 1; } 上面代码中,函 ...

  10. 18.Shiro与Springboot整合下登陆验证UserService未注入的问题

    Shiro与Springboot整合下登陆验证UserService未注入的问题 前言: 刚开始整合的情况下,UserService一执行,就会报空指针异常. 看了网上各位大神的讲解,什么不能用ser ...