JavaScript-牛客网-剑指offer(61-67)题解

剑指offer第51-60题解答(javascript)

本文章尽量用简洁的代码去完成题目要求,话不多说,上代码。

61.序列化二叉树

题目描述:请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
例如,我们可以把一个只有根节点为1的二叉树序列化为"1,",然后通过自己的函数来解析回这个二叉树

let arr = []
function Serialize(pRoot){
    // write code here
    if(!pRoot){
        arr.push('#')
    }else{
        arr.push(pRoot.val)
        Serialize(pRoot.left)
        Serialize(pRoot.right)
    } 
}
function Deserialize(s){
    // write code here
    let node = null
    if(!arr.length) return node;
    let num = arr.shift()
    if(typeof num == 'number'){
        node = new TreeNode(num)
        node.left = Deserialize(arr)
        node.right = Deserialize(arr) 
    }
    return node;
}

62.二叉搜索树的第k个结点

题目描述 : 给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

let arr =[];
function KthNode(pRoot, k)
{
    // write code here
    if(pRoot==null)
    {
        return null;
    }
    arr=[];
    get(pRoot);
    return arr[k-1];
  
}
function get(root){ //
    if(root!=null){
        get(root.left);
        arr.push(root);
        get(root.right);
    }
}

63.数据流中的中位数

题目描述 : 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

let arr = []
function Insert(num){
    // write code here
    for(let i=0;i<arr.length;i++){
        if(arr[i]>num){
            arr.splice(i,0,num)
            return
        }
    }
    arr.splice(i,0,num)
}
function GetMedian(){
	// write code here
    let len = arr.length
    if(len%2==0){
        return (arr[len/2] + arr[len/2 - 1])/2
    }else{
        return arr[Math.floor(len/2)]
    }
}

64.滑动窗口的最大值

题目描述 : 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
窗口大于数组长度的时候,返回空

function maxInWindows(num, size){
    // write code here
    let res = []
    if(num.length===0||size===0) return res;
    for(let i=0;i<=num.length-size;i++) {
        let temp = num.slice(i,i+size)
        res.push(Math.max(...temp))
    }
    return res;    
}

65.矩阵中的路径

题目描述 : 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如[[a,b,c,e],[s,f,c,s],[a,d,e,e]],矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

function hasPath(matrix, rows, cols, path){
    // write code here
   if(!matrix || !rows || !cols || rows*cols < path.length || path.length == 0) return false;
    let copy = matrix.split('');
    for(let i = 0; i < rows; i++){
        for(let j = 0; j < cols; j++){
            if(dfs(matrix, i, j, rows, cols, copy, path, 0))  return true;
        }
    }
    return false;
}
function dfs(matrix, i, j, rows, cols, copy, path, k){
    let index = i*cols + j;
    if(i < 0 || j < 0 || i>=rows||j>=cols||path[k] != matrix[index]||copy[index]==true)   return false;
    if(k == path.length - 1)  return true;
    copy[index] = true;
    if(dfs(matrix,i-1,j,rows,cols,copy,path,k+1)||
       dfs(matrix,i+1,j,rows,cols,copy,path,k+1)||
       dfs(matrix,i,j-1,rows,cols,copy,path,k+1)||
       dfs(matrix,i,j+1,rows,cols,copy,path,k+1)){
        return true;
    }
    copy[index] = false;
    return false;
}

66.机器人的运动范围

题目描述 : 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

function movingCount(m, n, k){
    // write code here
   let visited = [];
   for (let i = 0;i< n;i++) {
        visited.push([]);
        for (let j = 0;j <k;j++) {
            visited[i][j] = false;
        }
    }
  return moveCount(m,n,k, visited, 0, 0)
}
 
function moveCount(threshold, rows, cols, flag, i, j) {
  if (i < 0 || i >= rows || j < 0 || j >= cols || flag[i][j]) return 0
  let sum = 0
  let str = i + '' + j
  for (let k = 0; k < str.length; k++) {
    sum += parseInt(str[k])
  }
  if (sum > threshold) return 0
  flag[i][j] = true
  return 1 + moveCount(threshold, rows, cols, flag, i+1, j) +
    moveCount(threshold, rows, cols, flag, i-1, j) +
    moveCount(threshold, rows, cols, flag, i, j+1) +
    moveCount(threshold, rows, cols, flag, i, j-1)
}

67.剪绳子

题目描述 : 给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],…,k[m]。请问k[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

//不要在javascript V8里运行,在Node里运行!!!!!
function cutRope(number){
    // write code here
    if(number < 2||number>60) return 0;
    if(number===2) return 1;
    if(number===3) return 2;
    let a=Math.floor(number/3),b=number%3;
    switch(b){
        case 0:return Math.pow(3,a);
        case 1:return Math.pow(3,a-1)*4;
        case 2:return Math.pow(3,a)*2;   
    }
}
module.exports = {
    cutRope : cutRope
};

全剧终。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值