剑指offer js算法练习(1-10)
1.二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
时间限制:1秒 空间限制:32768K
分析:由于每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序,所以右上角的数字就是该行的最大值,该列的最小值。则可以通过把目标数与右上角的数字比较来判断其位置,如果目标数比该数字小,由该数字为该列的最小值可得这一列都不会有目标数,我们就可以将该列删除,并得到新的二维数组,再次比较目标数与右上角的数字的大小关系。如果目标数比该数字大,由该数字为该行的最大值可得这一行都不会有目标数,我们就可以将该行删除,并得到新的二维数组,再次比较目标数与右上角的数字的大小关系。如果目标数与右上角的数字相等,则返回true,找到了该目标数。如果当行数和列数都被删完了还没找到,则该二维数组中就没有该目标数。
function Find(target, array)
{
if(array==undefined||array.length<0||array[0].length<0){
return false;
}
let rows=array.length;
let columns=array[0].length;
let row=0;
let column=columns-1;
while(row<rows&&column>=0){
if(array[row][column]==target){
return true;
}
if(array[row][column]>target){
column--;
}else{
row++;
}
}
return false;
}
2.替换空格
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
时间限制:1秒 空间限制:32768K
分析:这里用replace+正则表达式即可替换。
function replaceSpace(str)
{
return str.replace(/ /g,'%20')
}
3.从头到尾打印链表
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。链表节点如下:
function ListNode(x){
this.val = x;
this.next = null;
}
时间限制:1秒 空间限制:32768K
分析:首先我们应该判断链表是否存在,如果链表存在的话,就用一个循环来判断节点是否存在,依次将节点中的值放入栈(题目要求从尾到头的顺序)即可。
function printListFromTailToHead(head)
{
if(head==undefined)
{
return 0;
}else
{
var arr=new Array();
var curr=head;
while(curr)
{
arr.push(curr.val);
curr=curr.next;
}
return arr.reverse();
}
}
4.重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。树节点如下:
function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
}
时间限制:1秒 空间限制:32768K
分析:首先我们要知道前序遍历的顺序是根左右,中序遍历的顺序是左根右。前遍历的第一个数总是根,所以我们就可以在前序遍历中先找到根,再在中序遍历中分别找到左子树和右子树,然后再分别在左子树和右子树中按照相同的方法去找它们的根节点,左右子树,直到在某个子树中的前序和后序遍历的长度都为0。由此我们可以写出如下的递归代码:
function reConstructBinaryTree(pre, vin)
{
if(pre.length==0&&vin.length==0)
{
return null;
}
var index=vin.indexOf(pre[0]);
var left=vin.slice(0,index);
var right=vin.slice(index+1);
var root=new TreeNode(pre[0]);
root.left=reConstructBinaryTree(pre.slice(1,index+1),left);
root.right=reConstructBinaryTree(pre.slice(index+1),right);
return root;
}
5.用两个栈实现队列
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
时间限制:1秒 空间限制:32768K
分析:首先我们要明白栈的特点是后进先出,队列的特点是先进先出。这里我们可以用栈stack1压入队列,不做特殊处理,就用栈的方法压入。再在另一个用于Pop的方法中,把stack1中数依次弹出并压入栈stack2,这样就满足了最先进入栈stack1在栈stack2的栈顶,由于Pop操作每次只弹出一个值,所以需要弹出stack2的栈顶值,用一个变量存起来,然后再把stack2中数依次弹出并压入栈stack1,以便下次正常压入弹出,最后返回变量即可。
var stack1=new Array();
var stack2=new Array(); function push(node)
{
stack1.push(node);
}
function pop()
{
var temp=stack1.pop();
while(temp){
stack2.push(temp);
temp=stack1.pop();
}
var result=stack2.pop();
temp=stack2.pop();
while(temp){
stack1.push(temp);
temp=stack2.pop();
}
return result;
}
6.旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
时间限制:3秒 空间限制:32768K
分析:这道题可以用二分法来做,但是会出现超时,所以用js的Math.min.apply(null,arr)方法来求是最高效的。
function minNumberInRotateArray(rotateArray)
{
if(rotateArray.length==0){
return 0;
}
return Math.min.apply(null,rotateArray);
}
7.斐波那契数列
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39
时间限制:1秒 空间限制:32768K
分析:斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368........这个数列从第3项开始,每一项都等于前两项之和。解决斐波那契数列可以使用递归的解法,但是这个却不是最优解,因为递归会产生很多重复的计算。为避免重复计算,我们可以根据f(0)和f(1)算出f(2),再根据f(1)和f(2)算出f(3)......依次类推就可以算出第n项了。
function Fibonacci(n){
if(n<0||n>39){
return;
}
if(n==0){
return 0;
}
if(n==1){
return 1;
}
var fibNMinusOne=0;
var fibNMinusTwo=1;
var fibN=0;
for(var i=2;i<=n;i++){
fibN=fibNMinusOne+fibNMinusTwo;
fibNMinusOne=fibNMinusTwo;
fibNMinusTwo=fibN;
}
return fibN;
}
8.跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
时间限制:1秒 空间限制:32768K
分析:首先我们考虑最简单的情况。如果只有1级台阶,那显然只有一种跳法。如果有2级台阶,那就有两种跳法:一种是分两次跳,每次跳1级;另一种就是一次跳2级。接着我们再来讨论一般情况。我们把n级台阶时的跳法看成n的函数,记为f(n)。当n>2时,第一次跳的时候就有两种不同的选择:一次第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);二是第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目,即为f(n-2)。因此,n级台阶的不同跳法的总数f(n)=f(n-1)+f(n-2)。这实际上就是斐波那契数列。
function jumpFloor(number){
if(number <= 0){
return 0;
}
if(number == 1){
return 1;
}
if(number == 2){
return 2;
}
var jumpNMinusOne=1;
var jumpNMinusTwo=2;
var jumpN=0;
for(var i=3;i<=number;i++){
jumpN=jumpNMinusOne+jumpNMinusTwo;
jumpNMinusOne=jumpNMinusTwo;
jumpNMinusTwo=jumpN;
}
return jumpN;
}
9.变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
时间限制:1秒 空间限制:32768K
分析:首先我们考虑最简单的情况。如果只有1级台阶,那显然只有一种跳法。如果有2级台阶,那就有两种跳法:一种是分两次跳,每次跳1级;另一种就是一次跳2级。如果只有3级台阶,那就有4种跳法:①分三次跳,每次跳1级;②分二次跳,第一次跳2级第二次跳1级;③分二次跳,第一次跳1级第二次跳2级;④分一次跳,直接跳3级。接着我们再来讨论一般情况。我们把n级台阶时的跳法看成n的函数,记为f(n)。当n>1时,第一次跳的时候就有n种不同的选择:第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目,即为f(n-2);同理第一次跳n-1级,此时跳法数目等于后面剩下的1级台阶的跳法数目,即为f(1);第一次跳n级,此时跳法数目等于后面剩下的0级台阶的跳法数目,即为f(0)也就是0次。因此,n级台阶的不同跳法的总数f(n)=f(n-1)+f(n-2)+...+f(0)。又因f(n-1)=f(n-2)+f(n-3)+...+f(0)。所以f(n)=2*f(n-1)。
function jumpFloorII(number)
{
if(number <= 0){
return 0;
}
if(number == 1){
return 1;
}
var jumpNMinus=1;
var jumpN=0;
for(var i=2;i<=number;i++){
jumpN=jumpNMinus*2;
jumpNMinus=jumpN;
}
return jumpN;
}
10.矩形覆盖
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
时间限制:1秒 空间限制:32768K
分析:
我们讨论一般情况。我们把放的方法的看成n的函数,记为f(n)。当第一个小矩形这样横着放时,剩下的放法即为f(n-2)。
当第一个小矩形这样竖着放时,剩下的放法即为f(n-1)。由此我们可以得到f(n)=f(n-1)+f(n-2),所以这个问题其实还是斐波那契数列。
function rectCover(number)
{
if(number==1){
return 1;
}
if(number==2){
return 2;
}
var rectNMinusOne=1;
var rectNMinusTwo=2;
var rectN=0;
for(var i=3;i<=number;i++){
rectN=rectNMinusOne+rectNMinusTwo;
rectNMinusOne=rectNMinusTwo;
rectNMinusTwo=rectN;
}
return rectN;
}
剑指offer js算法练习(1-10)的更多相关文章
- 剑指Offer——分治算法
剑指Offer--分治算法 基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更 ...
- 剑指Offer——贪心算法
剑指Offer--贪心算法 一.基本概念 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解.虽然贪心算法不能对 ...
- 《剑指offer》算法题第十二天
今天是<剑指offer>算法题系列的最后一天了,但是这个系列并没有包括书上的所有题目,因为正如第一天所说,这些代码是在牛客网上写并且测试的,但是牛客网上并没有涵盖书上所有的题目. 今日题目 ...
- 剑指Offer——回溯算法解迷宫问题(java版)
剑指Offer--回溯算法解迷宫问题(java版) 以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍.设计程序,对任意设定的迷宫,求出从入口到出口的所有通路. 下面我们来详细讲一 ...
- 剑指Offer——回溯算法
剑指Offer--回溯算法 什么是回溯法 回溯法实际是穷举算法,按问题某种变化趋势穷举下去,如某状态的变化用完还没有得到最优解,则返回上一种状态继续穷举.回溯法有"通用的解题法"之 ...
- 剑指Offer——动态规划算法
剑指Offer--动态规划算法 什么是动态规划? 和分治法一样,动态规划(dynamic programming)是通过组合子问题而解决整个问题的解. 分治法是将问题划分成一些独立的子问题,递归地求解 ...
- JS数据结构与算法 - 剑指offer二叉树算法题汇总
❗❗ 必看经验 在博主刷题期间,基本上是碰到一道二叉树就不会碰到一道就不会,有时候一个下午都在搞一道题,看别人解题思路就算能看懂,自己写就呵呵了.一气之下不刷了,改而先去把二叉树的基础算法给搞搞懂,然 ...
- 《剑指offer》算法题第一天
按照个人计划,从今天开始做<剑指offer>上面的算法题,练习平台为牛客网,上面对每道题都有充分的测试实例,感觉还是很不错的.今天下午做了四道题,分别为: 1. 二叉树的深度(书55题) ...
- 《剑指offer》算法题第十天
今日题目: 数组中的逆序对 两个链表的第一个公共节点 数字在排序数组中出现的次数 二叉搜索树的第k大节点 字符流中第一个不重复的字符 1. 数组中的逆序对 题目描述: 在数组中的两个数字,如果前面一个 ...
随机推荐
- DevExpress 14.2 批量汉化
1.下载DevExpress_.NET_Localization_Resources_14.2汉化包 2.解压后将zh-CN或zh-CHS复制到安装目录如D:\Program Files (x86)\ ...
- mysql六:mysql内置功能(视图、触发器、事务、存储过程、函数)
一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 通过使用视图可以把查询过程中的 ...
- scss-变量作用域
SCSS之所以便利,是因为它具有了编程语言的某些特性. 让原本规则刻板的CSS变的灵活起来,下面介绍一下SCSS中的作用域概念. 几乎所有编程语言都有作用域概念的涉及,原理大同小异,SCSS中的也是如 ...
- CSS 兼容性支持
CSS 兼容性支持 在一个CSS属性还没有成为标准之前,各浏览器厂商已经做了这个属性的实现,可能各浏览器实现不尽相同,所以加入属性前缀区分. safari , chrome:-webkit- oper ...
- 【基础笔记】tomcat安装后运行出现出现问题(the JRE_HOME environment variable is not defined correctly This environment variabl)
之前装好tomcat后正常运行 后来重装系统后,又一次配置环境时却报错. 在网上查找了两篇文章. https://blog.csdn.net/haleyliu123/article/details/ ...
- js实现瀑布流加载图片效果
今天学习了一个瀑布流加载效果,很多网站都有瀑布流效果,瀑布流就是很多产品显示在网页上,宽相同,高度不同,表现为多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.原理是:1. ...
- 使用weinre调试Web应用及PhoneGap应用
Web开发者经常使用Firefox的firebug或者Chrome的开发人员工具进行Web调试,包括针对JavaScript,DOM元素和CSS样式的调试.但是,当我们期望为移动Web站点或应用进行调 ...
- Java—集合框架List
集合的概念 现实生活中:很多的事物凑在一起 数学中的集合:具有共同属性的事物的总和 Java中的集合类:是一种工具类,就像是容器,存储任意数量的具有共同属性的对象 集合的作用 在类的内部,对数据进行组 ...
- BIEE入门(二)物理层的定义
使用BIEE的第一步是使用admintool去建立一个多维数据模型,而建立多维数据模型的第一步则是建立物理层,请注意因为BIEE本身并不存 储数据,所以所谓BIEE物理层的意义是需要在BIEE里建立各 ...
- 爬虫入门之handler与opener(三)
1 自定义opener opener是 urllib.request.OpenerDirector 的实例,我们之前一直都在使用的urlopen,它是一个特殊的模块构建好的opener 但是基本的ur ...