今日头条2018春招笔试题js版本

(蹭蹭热度,我也来写一下。注:以下全是js版本,不考虑性能,只为了实现。因为当时我在外面面试回来只有半小时考试了,下面代码是经过处理后的输入样例,也就是readline后经过处理的数据)

本文来自于我的github:https://github.com/lhyt/issue/issues/11

1.数字对去重后的个数

在n个元素的数组中,找到差值为k的数字对去重后的个数。
输入:第一行,n和k,n表示数字个数,k表示差值
第二行,n个正整数
案例:
in:
5 2
1 5 3 4 2
out:
3
思路:把重复的元素放到另一个数组temp,然后枚举第一个去重过的数组。对于k=0的情况,就只研究temp去重后的长度

function pair(arr,n){
    var temp = []
    var last = []
    var count = 0
    for(var i = 0;i<arr.length;i++){
        if(temp.indexOf(arr[i])==-1){
            temp.push(arr[i])//去重数组
        }else{
            last.push(arr[i])//多余的数的数组
        }
    }
    if(n){//如果差值不是0
        for(var j = 0;j<temp.length;j++){
        for(var k = 0;k<temp.length;k++){
            if(temp[k]+n==temp[j]){
                count++
            }else if(temp[k]-n==temp[j]){
                count++
            }
        }
    }
    count = count/2//因为都重复了一次
    }else{
        count = [...new Set(last)].length//如果差值是0直接返回多余数组去重的长度
    }
    return count
}

2. 最少操作步数

定义两个字符串变量:s和m,再定义两种操作,
第一种操作:
m = s;
s = s + s;
第二种操作:
s = s + m;
假设s, m初始化如下:
s = “a”;
m = s;
求最小的操作步骤数,可以将s拼接到长度等于n
输入一个整数n,表明我们需要得到s字符长度,0<n<10000

案例:
in:
6
out:
3

思路:利用广度优先搜索,假设左节点是操作1,右节点是操作2,这样子就形成了操作树。利用bfs的规则,把上层的父节点按顺序加入队列,然后从前面按顺序移除,同时在队列尾部加上移除的父节点的子节点。我这里,先把父节点拿出来对比,他的子节点放在temp,对比完了再把子节点追加上去

function bfs(n){
    if(n<2||n!==parseInt(n)||typeof n !=='number') return
    if(n==2) return 1
    var quene = [[2,1]]//从2开始
    var temp = []//存放父节点队列的子节点
    var count = 0
    var state = false//判断是否结束循环
    while(!state){
        while(quene.length){//如果队列不是空,从前面一个个取,并把他的子节点放在temp
            var arr = quene.pop()
            if(arr[0]==n){//找到了直接结束
                state = true
                break
            }
                temp.push([arr[0]*2,arr[1]*2])
                temp.push([arr[0]+arr[1],arr[1]])
        }
        count++//队列已经空,说明这层的节点已经全部检索完,而且子节点也保存好了
        quene = [...temp]//队列是子节点所有的元素集合,重复前面操作
        temp = []
    }
    return count
}

3.

今日头条6周年周年庆就要开始啦。活动主办方请你帮忙制作一个小彩蛋。你的程序需要读取一个表达式,并输出用字符6拼出的计算结果。相邻数字使用两个英文句号”.”间隔,如下是0123456789。

1

第一行为一个整数n
接下来n行,每一行为一个表达式
对于30%的数据,表达式仅包含’6’, ‘+’, ‘-‘三种字符
对于100%的数据,表达式仅包含’6’, ‘+’, ‘-‘, ‘‘四种字符。1≤n≤100,表达式长度不超过100,其中’+’, ‘-‘, ‘‘均为二元运算符。输出对于每组数据输出用字符6拼出的计算结果。
样例
in:
2
6+6
6*6
out:
不用我说了,自己想象

function sixsixsix(test){
    var n = test.length
    var str = ''
    var l1 = ['66666','....6','66666','66666','6...6','66666','66666','66666','66666','66666']
    var l2 = ['6...6','....6','....6','....6','6...6','6....','6....','....6','6...6','6...6']
    var l3 = ['6...6','....6','66666','66666','66666','66666','66666','....6','66666','66666']
    var l4 = ['6...6','....6','6....','....6','....6','....6','6...6','....6','6...6','....6']
    var l5 = ['66666','....6','66666','66666','....6','66666','66666','....6','66666','66666']
    var arr = [l1,l2,l3,l4,l5]//每一个数字都有5行 
    for(var i = 0;i<n;i++){
        var exp = test[i]
        var res = eval(exp)+''//计算给出的表达式结果
        for(var j = 0;j<5;j++){//因为每一个数字都是5行,一行一行拼接
            for(var k = 0;k<res.length;k++){//对计算结果每一位数字进行处理
                if(k==0)str += arr[j][res[k]]//第一位数字不需要..号,第j行第k个,k刚刚好和列表对应
               else  str +='..'+arr[j][res[k]]
            }
            str += '\n'
        }
        str = str.slice(0,-1)//去掉多余的换行
        console.log(str)
        str = ''
    }
}

4.magic操作

给一个包含n个整数元素的集合a,一个包含m个整数元素的集合b。
定义magic操作为,从一个集合中取出一个元素,放到另一个集合里,切操作过后每个集合的平均值都大于操作前。
注意一下两点:

不可以把一个集合的元素取空,这样就没有平均值了
值为x的元素从集合b取出放入集合a,但集合a中已经有值为x的元素,则a的平均值不变(因为集合元素不会重复),b的平均值可能会改变(因为x被取出了)
问最多可以进行多少次magic操作?

输入的第一行为两个整数n,m
第二行n个整数,表示集合a中的元素
第三行m个整数,表示集合b中的元素
对于100%的数据,1

function magic(a,b){
    function ave(a){
        return a.reduce(function(x,s){
            return x+s
        },0)/a.length
    }
    var max = ave(a)>ave(b)?a:b
    var min = ave(a)<ave(b)?a:b
    max = max.sort((a,b)=>a-b)//确定大小集合,并对大集合排序
    var i = 0
    var count = 0
        while(max[i]<ave(max)){//取大集合的小于平均值的元素
        if(min.indexOf(max[i])!=-1){
            i++//小集合有大集合元素,直接跳过 
        }else{
            if(max[i]>ave(min)){//取出的元素要大于小集合的平均值
                var temp = max.splice(i,1)[0]//满足条件,移动到小集合
                min.push(temp)
                count++     
            }

        }

    }
    return count
}

5.跳板游戏

小T最近迷上一款跳板小游戏
已知空中有N个高度互不相同的跳板,小T刚开始在高度为0的地方,每次跳跃可以选择与自己高度绝对值小于等于H的跳板,跳跃过后到达以跳板为轴的镜像位置,问小T在最多跳K次的情况下最高能跳多高?(任意时刻,高度不能为负)

输入第一行三个整数N,K,H ,以下N行,每行一个整数Ti,表示第i个跳板的离地高度
输出一个整数,表示最高能跳到的高度。

样例
in:
3 3 2
1
3
6
out:
8
思路:
直接从头开始,一直遍历k次。主要是理解题意:跳跃过后到达以跳板为轴的镜像位置。这句话我纠结了很久,其实就是你跳了多高(起跳点到板),板就把你弹起来多高(2倍这个高度),所以新位置=原位置+(跳板高度-原位置)*2

function h(arr,k,n){
    arr = arr.sort((a,b)=>a-b)
    var res = 0
    var i = 0
    var jump
    while(k--){
        while(arr[i]-n<=res&&arr[i]>res){//在能跳到的情况下,取最大的那个
            jump = arr[i++]
            res += (jump-res)*2//新位置=原位置+(跳板高度-原位置)*2
        }
        if(arr[i]-n>res){
            break
        }
    }
    return res
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值