今日题目:

  1. 斐波那契数列
  2. 青蛙跳台阶问题(及其变种:变态跳台阶)
  3. 矩形覆盖
  4. 旋转数组的最小数字
  5. 矩阵中的路径
  6. 机器人的运动范围

细心的同学会发现,第1,2,3题其实对应的是《剑指》书上的同一道题目,即第10题斐波那契数列,这类问题属于递归问题,虽然思路比较简单,但却是属于那种不看答案想不出来,看了答案恍然大悟的题目,因此在平时同学们和博主都应该多练练这一类型的题目,培养这种递归的思维。有趣的是,博主在做题的时候发现这三道题目是可以用动态规划的思路来解决的,而且往往动态规划的所用的时间是要低于递归的。在后文中会以矩形覆盖为例子来说明。

第5,6两题是回溯法的题目,在leetcode上有不少这一类型的题,只要多做练习,这一类型的题目还算是比较容易上手的。本文只说明第6题。

3.矩行覆盖

题目描述:
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 思路:
以n=8为例,我们先把2*8矩形的覆盖方法记为f(8)。当用一个2*1的小矩形取覆盖大矩形的最左边时有两种选择:竖着放或横着放。如果选择竖着放,那么右边还剩下2*7的区域,也就是f(7);如果横着放在左上角,左下角必须也放置一个矩形,那么右边还剩下2*6的区域,也就是f(6)。所以我们有f(8)=f(7)+f(6)。从这边我们可以看出来,其实这就是一个斐波那契数列。

理清思路后,接下来我们分别用递归以及动态规划的方法来实现。

递归代码如下:

 public class Solution {
public int RectCover(int target) {
if(target == 0) return 0;
if(target == 1) return 1;
if(target == 2) return 2;
return RectCover(target-1)+RectCover(target-2);
}
}

代码比较简单、清晰,但是效率非常的低,他的时间复杂度不难推出来是成指数的。在牛客网上的运行时间为447ms。

接下来我们看一下动态规划是如何解决的,代码如下:

 public class Solution {
public int RectCover(int target) {
if(target == 0) return 0;
int[] dp = new int[target+1];
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i <= target; i++){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[target];
}
}

很明显,这段代码的时间复杂度仅为O(n),当然空间复杂度也为O(n),所以,你也可以这么做:

 public class Solution {
public int RectCover(int target) {
if(target == 0) return 0;
int num1 = 1;
int num2 = 1;
int res = 1;
for(int i = 2; i <= target; i++){
res = num1 + num2;
num1 = num2;
num2 = res;
}
return res;
}
}

这样空间复杂度也就仅为常数啦。动态规划在同样的条件下运行时间仅为12ms。

4.旋转数组的最小数字

题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

这题在leetcode上面是有原题的,当时博主在做的时候并没有太多的想法,直接从后往前遍历数组,如果某个数比它前面的数字要小的话,那么这个数就是最小的,时间复杂度为O(n)。代码如下:

 public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array.length ==0) return 0;
for(int i = array.length-1; i >0; i--){
if(array[i-1] > array[i])
return array[i];
}
return array[0];
}
}

但是在《剑指》上,这题有一个时间复杂度为O(logn)的思路:利用二分查找的思路来寻找最小数字,具体的过程阐述起来过于复杂,感兴趣的同学可以阅读书上第83页,这边只贴出代码:

 public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array.length ==0) return 0;
int s = 0;
int e = array.length - 1;
if(array[s] < array[e])//表示旋转了0个数字到数组后面
return array[s];
while(s != e){
if(e - s == 1)
return array[e];
int mid = (s+e)/2;
if(array[mid] == array[s] && array[mid] == array[e])//处理特殊情况
return orderFind(array,s,e);
if(array[mid] >= array[s])
s = mid;
else if(array[mid] <= array[e])
e = mid;
}
return array[s];
}
public int orderFind(int[] array,int start,int end){
int res = array[start];
for(int n:array){
res = (n < res)?n:res;
}
return res;
}
}

6. 机器人的运动范围

题目描述:
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子? 思路:
这是比较直接的回溯法的题目,首先使用一个数组来标记机器人已经走过的放歌,防止重复,然后使用回溯法让机器人运动,每次运动到一个方格都判断一下是否合法,如果合法,计数器加一接着往下走;否则返回0;

代码如下:

 public class Solution {
public int movingCount(int threshold, int rows, int cols)
{
boolean[][] visited = new boolean[rows][cols];
return movingCount(threshold,visited,rows,cols,0,0);
} public int movingCount(int k,boolean[][] visited,int rows,int cols,
int row,int col)
{
if(row < 0 || row >= rows||
col < 0 || col >= cols || visited[row][col])
return 0;
visited[row][col] = true;
int sum = 0;
int row_tmp = row;
int col_tmp = col;
do{
sum += (row%10);
row /= 10;
}while(row > 0); do{
sum += (col%10);
col /= 10;
}while(col > 0);
row = row_tmp;
col = col_tmp;
if(sum > k)
return 0;
else{
return movingCount(k,visited,rows,cols,row+1,col)+
movingCount(k,visited,rows,cols,row-1,col)+
movingCount(k,visited,rows,cols,row,col+1)+
movingCount(k,visited,rows,cols,row,col-1)+1;
}
}
}

《剑指offer》算法题第三天的更多相关文章

  1. 剑指offer算法题

    数组中只出现一次的数字(一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字): 解法在于位运算中的异或,直接异或可以得到这两个数的异或,按照最后的有效数字位可以 ...

  2. 剑指offer算法总结

    剑指offer算法学习总结 节选剑指offer比较经典和巧妙的一些题目,以便复习使用.一部分题目给出了完整代码,一部分题目比较简单直接给出思路.但是不保证我说的思路都是正确的,个人对算法也不是特别在行 ...

  3. 剑指Offer——算法复杂度中的O(logN)底数是多少

    剑指Offer--算法复杂度中的O(logN)底数是多少 前言 无论是计算机算法概论.还是数据结构书中,关于算法的时间复杂度很多都用包含O(logN)这样的描述,但是却没有明确说logN的底数究竟是多 ...

  4. 剑指 offer 第一题: 二维数组中的查找

    打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣

  5. 剑指Offer编程题2——替换空格

    剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...

  6. 剑指Offer编程题1——二维数组中的查找

    剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...

  7. 剑指offer编程题66道题 36-66

    36.两个链表的第一个公共节点 题目描述 输入两个链表,找出它们的第一个公共结点. 1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点. 这种算 ...

  8. 牛客网剑指offer刷题总结

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

  9. 剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现

    用字符串或者数组表示大数是一种很简单有效的表示方式.在打印1到最大的n为数的问题上采用的是使用数组表示大数的方式.在相关题实现任意两个整数的加法.减法.乘法的实现中,采用字符串对大数进行表示,不过在具 ...

  10. 剑指offer刷题(Tree)

    开篇 二刷剑指offer了,本来用Tyora记的笔记,发现字数到四万了就变得好卡o(╥﹏╥)o,刚好开始写博客,就转过来吧,记下来子自己看.不废话,开刷... JZ26. 树的子结构 输入两棵二叉树A ...

随机推荐

  1. PHP与MySQL的连接

    一.PHP的相关扩展 PHP与MySQL的交互需要要借助PHP提供的数据库扩展,在PHP中提供了多种数据库扩展,常用的MySQL扩展, MySQLi扩展和PDO扩展. 1.三者各自的特点: MySQL ...

  2. Java加密数据库

    一.背景 数据库配置以明文方式展示如图,会造成安全隐患,如果有黑客入侵会造成密码泄露,信息窃取和破坏等. 二.加密步骤 1.对数据库信息加密: 对数据库中的账号和密码信息进行加密(选择一种算法)然后替 ...

  3. JS基础_强制类型转换-String

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. SQLAlchemy技术手册

    一.ORM 框架简介 对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的.面向对象的开发方法是当今企业级应用开发环境中的主流开发方法 ...

  5. apply,call 和 bind 有什么区别

    三者都可以把函数应用到其他对象上,不是自身对象,apply,call是直接执行函数调用,bind是绑定,执行需要再次调用,apply和call的区别是apply接受数组作为参数,而call是接受逗号分 ...

  6. 好用的 python 工具集合

    图标处理小程序, 妈妈再也不用担心我不会制作图标了 # PythonMargick包可以到Unofficial Windows Binaries for Python Extension Packag ...

  7. Idea java 程序打jar包(maven)

    1.准备好控制台程序 2.引用的项目打包(公共类接口) 3.开发打包 点击运行 打包结果如下

  8. iOS资料大全

    1.创建自己的Xcode 模板类工程 https://mp.weixin.qq.com/s?__biz=MzAxMzE2Mjc2Ng==&mid=2652155923&idx=1&am ...

  9. 查询服务商的当月提审限额和加急次数(Quota) 调用遇到问题的来说说是什么情况{"errcode":-1,"errmsg":"system error hint: [_KbPJA05231543]"}

    感觉完全是按照微信官方的要求来的,还是提示错误.大家有遇到吗?在微信开发者社区里搜索相关问题,也是有人遇到这样的错误. 还是根据社区里说的,换过用开放平台的component accesstoken  ...

  10. appium 自动化测试框架详读(一)

    appium框架使用的过程记录,开始使用markdown来语法来编写,不知道博客园是否会支持markdown语法 ***1. appium原理* appium启动时,创建一个http://127.0. ...