牛客网刷题1(6道题)

来源:牛客网

1.函数柯里化

题目链接:https://www.nowcoder.com/practice/bb78d69986794470969674a8b504ac00?tpId=6&tqId=10977&tPage=2&rp=2&ru=/ta/js-assessment&qru=/ta/js-assessment/question-ranking
题目描述
已知 fn 为一个预定义函数,实现函数 curryIt,调用之后满足如下条件:
1、返回一个函数 a,a 的 length 属性值为 1(即显式声明 a 接收一个参数)
2、调用 a 之后,返回一个函数 b, b 的 length 属性值为 1
3、调用 b 之后,返回一个函数 c, c 的 length 属性值为 1
4、调用 c 之后,返回的结果与调用 fn 的返回值一致
5、fn 的参数依次为函数 a, b, c 的调用参数
示例1
输入
var fn = function (a, b, c) {return a + b + c}; curryIt(fn)(1)(2)(3);
输出
6
笔记:
柯里化:把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
题目分析:
将预定义的函数的参数逐一传入到curryIt中,当参数全部传入之后,就执行预定义函数。

  • 首先要获得预定义函数的参数个数fn.length。
  • 然后声明一个空数组去存放这些参数。
  • 返回一个匿名函数接收参数并执行,当参数个数小于fn.length,则再次返回该匿名函数,继续接收参数并执行,直至参数个数等于fn.length。
  • 最后,调用apply执行预定义函数。
function curryIt(fn) {
     //获取fn参数的数量
     var n = fn.length;
     //声明一个数组args
     var args = [];
     //返回一个匿名函数
     return function(arg){
         //将curryIt后面括号中的参数放入数组
         args.push(arg);
         //如果args中的参数个数小于fn函数的参数个数,
         //则执行arguments.callee(其作用是引用当前正在执行的函数,这里是返回的当前匿名函数)。
         //否则,返回fn的调用结果
         if(args.length < n){
            return arguments.callee;
         }else return fn.apply("",args);
     }
 }

2.剪绳子

题目链接:https://www.nowcoder.com/practice/57d85990ba5b440ab888fc72b0751bf8?tpId=13&&tqId=33257&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking
题目描述
给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]xk[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
输入描述:
输入一个数n,意义见题面。(2 <= n <= 60)
输出描述:
输出答案。
示例1
输入
8
输出
18
笔记:
举例子,看规律。
4 : 2x2
5 : 2x3
6 : 3x3
7 : 2x2x3 或者4x3
8 : 2x3x3
9 : 3x3x3
10:2x2x3x3 或者4x3x3
11:2x3x3x3
12:3x3
13:2x2x3x3x3 或者4x3x3x3

  • 首先判断k[0]到k[m]实际上只可能是2、3、4(4=2x2)。
  • 其次看2和3的数量,2的数量肯定小于3个:2x2x2<3x3。
  • 用n除以3,根据得到的余数判断是一个2还是两个2还是没有2。
    *两个特殊情况: 由于题目规定m>1,所以2只能是1x1,3只能是2x1。
function cutRope(number)
{
    if(number==2){
        return 1;
    }
    if(number==3){
        return 2;
    }
    var x = number % 3;
    var y = Math.floor(number / 3);
    if(x==0){
        return Math.pow(3,y);
    }else if(x==1){
        return 2*2*Math.pow(3,y-1);
    }else{
        return 2*Math.pow(3,y);
    }        
}

3.二维数组

题目链接:https://www.nowcoder.com/practice/abc3fe2ce8e146608e868a70efebf62e?tpId=13&&tqId=11154&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking
题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
分析:
观察数组规律
按照题目要求,数组的特点是:每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。

function Find(target, array)
{
    const len = array.length;
    if(!len){
        return false;
    }
    var len_1 = array[0].length;
    if(!len_1){
        return false;
    }
    let row = 0;
    let col =len_1-1;
    while(row < len && col>=0){
        if(array[row][col] === target){
            return true;
        }
        else if(array[row][col] > target){
            --col;
        }
        else{
            ++row;
        }
    }
    return false;
}

4.跳台阶

题目链接:https://www.nowcoder.com/practice/8c82a5b80378478f9484d87d1c5f12a4?tpId=13&&tqId=11161&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
分析:
找规律
n=1:1种方法;
n=2:2种方法;
n=3:3种方法;
n=4:5种方法;
n=5:8种方法;
n=6:13种方法;
所以,本质上是斐波那契数列:f(n)=f(n-1)+f(n-2)。

function jumpFloor(number)
{
    if(number <= 3)
         return number;
    else{
        var f0 = 2;
        var f1 = 3;
        for(var i=4; i<=number; i++){
            f2 = f0 + f1;
            f0 = f1;
            f1 = f2;
        }
        return f2;  
    }
}

5.调整数组顺序

题目链接:https://www.nowcoder.com/practice/beb5aa231adc45b2a5dcc5b62c93f593?tpId=13&&tqId=11166&rp=2&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
分析:

  • 删除原数组中的偶数。
  • 把原数组中的偶数按顺序保存在新的数组中。
  • 把只有奇数的数组和只有偶数的数组拼接成新数组。
function reOrderArray(array)
{
    //删除数组种的偶数,返回新数组(只包含奇数)
    var odd = array.filter(function(value,index,array){
        return value % 2 !== 0;
    });
    var newArray=[];
    //把数组中的偶数按顺序添加到index中
    for(var i=0; i<array.length; i++){
        if(array[i]%2 == 0){
            newArray.push(array[i]);
        }
    }
    //奇数数组和偶数数组拼接
    var result = odd.concat(newArray);
    return result;
}

6.顺时针打印矩阵

题目链接:https://www.nowcoder.com/practice/9b4c81a02cd34f76be2659fa0d54342a?tpId=13&&tqId=11172&rp=3&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
分析:
顺时针打印就是按照顺时针转圈打印,打印方向:

  1. 从左到右;
  2. 从上到下;
  3. 从右到左;
  4. 从下到上。
    因此,定义四个边界:左、右、上、下。
    for循环遍历行走的方向。
    根据边界范围判断是否打印完成。
function printMatrix(matrix)
{
    var row = matrix.length;
    var col = matrix[0].length;
    var left = 0;
    var right = col-1;
    var top = 0;
    var bottom = row-1;
    var arr = [];
    if(row == 0 || col == 0){
        return arr;
    }
    while(left<=right && top<=bottom){
        //从左到右
        for(var i=left;i<=right;i++)
            arr.push(matrix[top][i]);
         //从上到下
        for(var i=top+1;i<=bottom;i++)
            arr.push(matrix[i][right]);
        if(top!=bottom){
            //从右到左
            for(var i=right-1;i>=left;i--)
                arr.push(matrix[bottom][i]);
        }
         if(left!=right){
             // 从下到上
            for(var i=bottom-1;i>top;i--)
                arr.push(matrix[i][left]);
        }
        left++;
        right--;
        top++;
        bottom--;
    }
    return arr;
}
发布了22 篇原创文章 · 获赞 0 · 访问量 376

猜你喜欢

转载自blog.csdn.net/weixin_41796393/article/details/104067007