美文网首页
牛客网前端在线编程题

牛客网前端在线编程题

作者: 苏敏 | 来源:发表于2017-11-06 10:30 被阅读377次

    最近学了一些前端的js,但是觉得概念是知道了点,但是还是不会下手,就拿牛客网的编程题练练手吧,主要是学习,我把我自己做的放在上面,别人好的代码我会贴出来以供自己学习。(在学习过程中发现牛客网的测试用例对箭头函数的支持有问题,注意下~)

    1.查找数组元素的位置

    image.png
    function indexOf(arr, item) {
        if(Array.prototype.indexOf){    //判断浏览器是否支持indexOf方法
            return arr.indexOf(item);
        }else{
            for(var i=0;i<arr.length;i++){
                if(arr[i]===item){
                    return i;
                }
            }
        }
        return -1;
    }
    

    2.计算给定数组 arr 中所有元素的总和

    image.png
    //我的做法,利用求和公式
    function sum(arr) {  
            return (arr[arr.length-1]+arr[0])*2;
    }
    
    
    //-----------------别人的代码-----------------
    
    
    
    
    //递归  (不建议使用)
    function sum(arr) {
        var len = arr.length;
        if(len == 0){
            return 0;
        } else if (len == 1){
            return arr[0];
        } else {
            return arr[0] + sum(arr.slice(1));
        }
    }
    
    
    //常规循环
    function sum(arr) {
        var s = 0;
        for (var i=arr.length-1; i>=0; i--) {
            s += arr[i];
        }
        return s;
    }
    
    //函数式编程map-reduce 
    function sum(arr) {
        return arr.reduce(function(prev, curr, idx, arr){
            return prev + curr;
        });
    }
    
    //箭头函数写法 reduce (补充),但是牛客网的测试用例没有通过,我觉得是他们用例有点问题,方法是可行的
    function sum(arr) {
        return arr.reduce((a,b) => {return a+b})
    }
    
    //forEach  
    function sum(arr) {
        var s = 0;
        // 这三个参数分别表示数组的值,索引值和数组本身
        arr.forEach(function(val, idx, arr) {
            s += val;
        }, 0);
      
        return s;
    };
    
    //forEach的简化版 箭头函数在牛客网的测试用例没通过,自己在chrome浏览器上测可行
    function sum(arr) {
        var sum=0;
        //这里只有一个参数,表示当前数组的值
         arr.forEach(function(e){sum+=e;});
         return sum;
    }
    
    //eval    但是不推荐数据大或者用户输入的时候用
    function sum(arr) {
        return eval(arr.join("+"));
    };
    

    3.移除数组 arr 中的所有值与 item 相等的元素。不要直接修改数组 arr,结果返回新的数组

    image.png
    function remove(arr, item) {
        //声明一个空数组保存结果
        var temp = [];
        for(var i=0;i<arr.length;i++){
            if(arr[i]!=item){
                //如果arr[i]不等于item,就加入数组temp
                temp.push(arr[i]);
        }
        }
        return temp;
    }
    
    //使用forEach
    function remove(arr, item) {
        //声明一个空数组保存结果
        var temp = [];
        arr.forEach(function(e){
            if(e != item){
                temp.push(e);
            }        
        })
        return temp;
    }
    
    //Array.prototype.filter()
    function remove(arr,item){
        return arr.filter(function(ele){
             return ele != item;
        })
    }
    

    4.移除数组 arr 中的所有值与 item 相等的元素,直接在给定的 arr 数组上进行操作,并将结果返回

    image.png
    //再次吐槽一下牛客网的测试用例!!!,这种代码你也给过??
    function removeWithoutCopy(arr, item) {
        for(var i in arr){
           arr.splice(i,2);
        }
        return arr;
    }
    
    // 我的做法
    function removeWithoutCopy(arr, item) {
        for(var i=0; i<arr.length; i++){
            if(item == arr[i]){
                arr.splice(i,1);
                i--;
            }
        }
        return arr;
    }
    
    //看到一下小伙伴不错的思路
    //把数组看成是队列,等于item元素直接删除,不等于的,先push再删除。
    //估计有的小伙伴不是太明白这里的意思,arr.push(arr[0])会使第一个元素和最后一个元素相同,所以要删掉,arr[0]每次都是不同的元素,所以必须先定义出来。
    
    
    function removeWithoutCopy(arr, item) {
        var n=arr.length; 
         for(var i=0;i<n;i++){
             if(arr[0]!==item){ 
                 arr.push(arr[0]);
              }
                 arr.shift();
        }
        return arr;
    }
    
    
    // 倒着检测,不用考虑位置影响
    function removeWithoutCopy(arr, item) {
        for(i=arr.length-1;i>=0;i--){
           if(arr[i]==item){
                arr.splice(i,1);
              }
           }
        return arr;
    }
    

    第5题

    image.png
    //我的做法就是普通的迭代
    function append(arr, item) {
        var newArr =[];
        for(var i in arr){
            newArr.push(arr[i])
            }
        newArr.push(item);
        return newArr;
        }
    

    参考别人家的代码

    //修改一下我的for循环的位置
    function(arr, item) {
        var newArr = arr.slice(0);  // slice可以实现拷贝数组
        newArr.push(item);
        return newArr;
    };
    

    使用concat将传入的数组或非数组值与原数组合并,组成一个新的数组并返回

    function(arr, item) {
        return arr.concat(item);
    };
    

    使用slice()复制数组arr赋值给newArr ,用push()添加元素item,但注意push()方法修改原数组,它返回的是新的数组的长度,所以例子中return newArr.push(item);返回的是5;concat() 方方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

    第六题

    image.png

    这一题和上一题思路类似,但是不改变原数组要看清楚,slice方法用于提取原数组的一部分,返回一个新数组,原数组不变。

    function truncate(arr) {
        var newArr = arr.slice(0);
        newArr.pop();
        return newArr;
    // return arr.slice(0,-1);  也是可以的
    }
    

    第九题

    image.png

    这一题和第一题有类似的地方,首先可以想到concat拼接数组,所以我们可以做一个兼容性判断,如果浏览器支持这个方法我们就直接用,然后我们再考虑不兼容的问题, 也是和上面的思路一样,new一个空数组,通过slice复制数组达到不修改数组实现操作,然后把第二个数组循环push到新数组中,达到目的。

    function concat(arr1, arr2) {
        if(Array.prototype.concat){
            return arr1.concat(arr2);
        }else {
            var newArr = arr1.slice(0);
            for(var i in arr2){
                newArr.push(arr2[i]);
            }
            return newArr;
        }
    }
    

    第10题

    image.png
    function insert(arr, item, index) {
        var newArr = arr.slice(0);
        newArr.splice(index,0,item);
        return newArr;
    }
    

    本题我们可以很容易想到使用splice,但是注意splice是会修改原数组的,所以我们需要拿一个索引来操作,了解一下splice的参数,它算是修改数组的万金油了,eg:

    let arr = ['A','B','C','D','E'];
    arr.splice(2,1,'A','S');       //返回的是['A','B','C','A','S','E'] 
    //第一个参数表示从索引为2的地方开始
    //第二个参数表示往后删除多少个元素
    //后面的参数都是需要依次添加在操作的位置后
    

    第11题

    image.png

    题目本身很简单,但是我们需要多开阔思维,看看你和别人的代码有哪些不同,开动脑筋~

    function count(arr, item) {
        var count = 0;
        for(var i in arr){
            if(arr[i]===item)
                count++;
        }
        return count;
    }
    

    //别人的代码

    //filter  我觉得写的很漂亮
    function count(arr, item) {
        return arr.filter(function(a){
            return (a==item);
        }).length
    }
    
    //map()-->对数组中的每一项进行给定函数,
            //返回每次函数条用的结果组成的数组;
      function count(arr, item) {
          var count = 0;
          arr.map(function(a) {
              if(a === item) {
                  count++;
              }
          });
          return count;
      } 
    
    //forEach()-->对数组中的每一项运行传入的函数
       function count(arr, item) {
            var count = 0;
            arr.forEach(function(a) {
                a === item ? count++ : 0;
            });
            return count;
        }
    }
    

    第12题

    image.png

    这道题我觉得挺有意思的,想了半天,具体思路是这样的,首先了解如何判断元素是否重复,我们可以利用元素的arr.indexOf(elem) 和arr.lastIndexOf(elem)是否相等,如果相等就表示这个元素只出现了一次。再通过判断result.indexOf(e) === -1去除新数组的重复数据,但是这种做法复杂度太高了。后面发现最好能给结果排一下序,不过得自己写比较函数 ,知道就好了,不想写,太困了~

    function duplicates(arr) {
        var newArr=[];
        for(var i in arr){
        //判断是否是第一个出现,且不是最后一个出现
         if(arr.indexOf(arr[i]) == i && arr.lastIndexOf(arr[i]) != i){
              newArr.push(arr[i]);
          }  
        }
        return newArr;
    }
    
    

    我们看一下别的同学的代码

    function duplicates(arr) {
        return arr.filter( function( e , i ) {    
            return arr.lastIndexOf( e ) != i  &&  i == arr.indexOf( e )
        })
    }
     //利用filter方法会创建一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
    
    function duplicates(arr) {
        var result = [];
        arr.forEach(function(elem){
           if(arr.indexOf(elem) !=arr.lastIndexOf(elem) && result.indexOf(elem) == -1){
               result.push(elem);
           }
        });
        return result;
    }
    
    
    function duplicates(arr) {
         //声明两个数组,a数组用来存放结果,b数组用来存放arr中每个元素的个数
         var a = [],b = [];
         //遍历arr,如果以arr中元素为下标的的b元素已存在,则该b元素加1,否则设置为1
         for(var i = 0; i < arr.length; i++){
             if(!b[arr[i]]){
                 b[arr[i]] = 1;
                 continue;
             }
             b[arr[i]]++;
         }
         //遍历b数组,将其中元素值大于1的元素下标存入a数组中
         for(var i = 0; i < b.length; i++){
             if(b[i] > 1){
                 a.push(i);
             }
         }
         return a;
     }
    

    主要看一下最后一个同学的代码实现思路:
    将传入的数组arr中的每一个元素value当作另外一个新数组b的key,然后遍历arr去访问b[value],若b[value]不存在,则将b[value]设置为1,若b[value]存在,则将其加1。可以想象,若arr中数组没有重复的元素,则b数组中所有元素均为1;若arr数组中存在重复的元素,则在第二次访问该b[value]时,b[value]会加1,其值就为2了。最后遍历b数组,将其值大于1的元素的key存入另一个数组a中,就得到了arr中重复的元素。

    每次我看到一些大牛同学的思路这么独特我都感觉自己白学了~洗洗睡了

    第13题

    image.png
    function count(start, end) { //start & and 表示计算的次数
        //立即输出第一个值
        console.log(start++);
        function check(){
            if(start <= end){
                 console.log(start++);
             }else{
                 clearInterval(time);
             }
        }
        var time = setInterval(check,100);
        //返回一个对象
         return {
             cancel : function(){
                 clearInterval(time);
             }
         };
     }
    

    第一眼看到题目觉得还好,可是要返回一个对象这是最骚的,直接到end就调用原生的方法不就好了,非要多此一举,我觉得这样写就可以了

    function count(start, end) { //start & and 表示计算的次数
        console.log(start++);
        var time = setInterval(function(){
            if(start <= end){
                console.log(start++);
            }else{
                clearInterval(time);
            }
        },100);
    }
    

    接着看一下别的小伙伴怎么写的吧

    function count(start, end) {
        if(start <= end){
            console.log(start);
            start++;
            st = setTimeout(function(){count(start, end)}, 100);
        }
        return {
            cancel: function(){clearTimeout(st);}
        }
    }
    

    这个小伙伴是使用了setTimeout方法,思路挺好,利用setTimeout每次执行完就结束了且没有使用函数封装达到第一个数立即输出,但是代码有一些细节没处理好,修改一下

    function count(start, end) {
        if(start <= end){
            console.log(start++);  // 直接调用start++
            var st = setTimeout(function(){count(start, end)}, 100);  // 不要使用全局变量,不然严格模式会报错
        }
        return {
            cancel: function(){clearTimeout(st);}
        }
    }
    

    相关文章

      网友评论

          本文标题:牛客网前端在线编程题

          本文链接:https://www.haomeiwen.com/subject/deoxmxtx.html