网易2017秋招编程题集合+自己的结果

_John

前言

周末利用无聊的时间见识了一下网易的秋招编程题也尝试用javascript来实现,总体的难度对我来说简直是变态-_-!,不过最后总算在自己的能力范围内解决了六道,其中有一道是参考了另一位大神的思路最终用代码实现,还有一道反正我怎么想也想不出来~~有兴趣的大神们可以尝试一下让我观摩观摩哈哈,下面放题


1.回文序列

题目:
如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如:
{1, 2, 1}, {15, 78, 78, 15} , {112} 是回文序列,
{1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是回文序列。
现在给出一个数字序列,允许使用一种转换操作:
选择任意两个相邻的数,然后从序列移除这两个数,并用这两个数字的和插入到这两个数之前的位置(只插入一个和)。
现在对于所给序列要求出最少需要多少次操作可以将其变成回文序列。

输入例子:[1,1,1,3]

输出例子:2

我的思路:首先清楚了回文序列的定义之后我可以用输入的数组的字符串以及该数组倒序后的字符串进行比较,以此来作为是否是回文序列的判断,后观察发现若需要最少操作来实现回文序列则必须使数字较小的数据来与后一个数据相加,举输入例子来说,数组第一位和最后一位的数字是1比3小,那么我在相加的时候就得拿1和后面的数字相加才能尽可能的与末尾的3相等。

var result = 0;
function fn(arr){
    var revArr = arr.slice(0).reverse();
    if(revArr.join("")==arr.join("")){
        return result
    }
    else if (revArr[0]==arr[0]) {
        arr.shift();
        arr.pop()
        return fn(arr)
    }
    else {
        revArr.splice(0,2,revArr[0]+revArr[1])
        arr.splice(0,2,arr[0]+arr[1])
        arr[0]>revArr[0]?fn(revArr):fn(arr);
        return ++result
    }
}

var arr = [3,1,1,2,2]
console.log(fn(arr))

2.优雅的点

题目:
小易有一个圆心在坐标原点的圆,小易知道圆的半径的平方。
小易认为在圆上的点而且横纵坐标都是整数的点是优雅的,
小易现在想寻找一个算法计算出优雅的点的个数,请你来帮帮他。
例如:半径的平方如果为25
优雅的点就有:(+/-3, +/-4), (+/-4, +/-3), (0, +/-5) (+/-5, 0),一共12个点。
输出为一个整数,即为优雅的点的个数

输入例子:25

输出例子:12

我的思路:这题我在审题的时候误把园内的点也算在内了,其实只是要求在圆上的点既可,该题有点像数学里的勾股定理,同理,我在做判断的时候就是用半径的平方减去遍历的每一个坐标点的横坐标的平方的结果再进行一个开方,然后判断该数是否为整数,又因为该圆的圆心是坐标原点,那么符合条件的每一个坐标点都有4个方向,同时又要注意是否有坐标为0的情况,若有则减去4(例如:(0,+-5)和(+-5,0))

function fn(Powr){
    var sum = [];
    var less = 0;
    if(typeof Powr == "number"){
        for(var i=0;i<=Math.sqrt(Powr);i++){
            var coordinate = Math.sqrt(Powr-Math.pow(i,2))
            if(coordinate.toString().split(".")[1]==undefined){ //验证开方后是否为整数
                if(i==0){
                    less=4; //验证是否存在有圆点的情况
                }
                sum.push({i,coordinate})
            }
        }
        return sum.length*4-less
    }
    else{
        return "请输入数字好吗";
    }
}

var Powr = 25;
console.log(fn(Powr))

3.跳石板

题目:
小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3.......
这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,
小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。
小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
例如:
N = 4,M = 24:
4->6->8->12->18->24
于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板

输入例子:4 24

输出例子:5

我的思路:这题。。。我能力有限,思路只想到用穷举这个方法了,所以大神们如果感兴趣的话可以提供一下思路啊哈哈哈~

4.暗黑的字符串

题目:
一个只包含'A'、'B'和'C'的字符串,
如果存在某一段长度为3的连续子串中恰好'A'、'B'和'C'各有一个,那么这个字符串就是纯净的,
否则这个字符串就是暗黑的。例如:
BAACAACCBAAA 连续子串"CBA"中包含了'A','B','C'各一个,所以是纯净的字符串
AABBCCAABB 不存在一个长度为2的连续子串包含'A','B','C',所以是暗黑的字符串
你的任务就是计算出长度为n的字符串(只包含'A'、'B'和'C'),有多少个是暗黑的字符串。

输入例子:2,3

输出例子:9,21

我的思路:这题的话坦白讲考的并不是代码,而是数学!!一开始我想着就是用3的n次方减去纯净的字符串个数那么得出来的就是暗黑的字符串,但我看了下面这个图,我简直膜拜
图片描述

具体的代码实现比较简单,关键还是思路以及MATH!!

function fn(num){
    
    if(num==1){
        return 3
    }
    else if(num==2){
        return 9
    }
    else{
        return 2*fn(num-1)+fn(num-2)
    }

}

var num=3;
console.log(fn(num))

5.数字翻转

题目:
对于一个整数X,定义操作rev(X)为将X按数位翻转过来,并且去除掉前导0。例如:
如果 X = 123,则rev(X) = 321;
如果 X = 100,则rev(X) = 1.
现在给出整数x和y,要求rev(rev(x) + rev(y))为多少?

输入例子:123,100

输出例子:223

我的思路:该题相对来说不算很难,整体的思路就是利用数组里的reverse,关键就是如何把数字的每一位转为对应的数组

function rev(num){
    var revArr = num.toString().split("").reverse().join("");
    return parseInt(revArr)
}

var x = 123;
var y = 100;
console.log(rev(rev(x) + rev(y)))

6.最大的奇约数

题目:
小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。
一天小易遇到这样一个问题: 定义函数f(x)为x最大的奇数约数,x为正整数。 例如:f(44) = 11.
现在给出一个N,需要求出 f(1) + f(2) + f(3).......f(N)
例如: N = 7
f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。

输入例子:7

输出例子:21

我的思路:该题的题意不难理解,明白的题意实现起来并不难,这里我用approximately函数来获取我输入的数字的所有约数,再经过判断获取最大的奇数约数从而实现,一开始我想到的是递归方法,不过。。能不用递归就不用递归对吧^ ^

function fn(num){
    var sum = 0;
    for(var j=num;j>0;j--){
        var apprNum = approximately(j);
        for(var i=apprNum.length-1;i>=0;i--){
            if(apprNum[i]%2){
                sum += apprNum[i];
                break;
            }
        }
    }
    return sum
}

function approximately(num){
    var result = []
    for(var i=1;i<=num;i++){
        if(num%i==0){
            result.push(i)
        }
    }
    if(result.length>0){
        return result
    }else{
        return false
    }
}

console.log( fn(7) )

7.买苹果

题目:
小易去附近的商店买苹果,奸诈的商贩使用了捆绑交易,
只提供6个每袋和8个每袋的包装(包装不可拆分)。 可是小易现在只想购买恰好n个苹果,小易想购买尽量少的袋数方便携带。
如果不能购买恰好n个苹果,小易将不会购买。

输入例子:20

输出例子:3

我的思路:输出的结果只能是偶数,且每次包装袋子的时候都是尽量选择8个每袋包装的袋子,这样可以尽可能用最少的袋子来购买苹果,所以我列举了前几个比较特殊的选袋情况作为递归的判断条件(用一次递归嘿嘿),代码如下

var freq = 0;
function fn(num){
    if(!(num%2)&&num>=12){
        if(num==12||num==14||num==16){
            return freq+=2;
        }
        else if(num==18){
            return freq+=3;
        }
        else{
            ++freq
            return fn(num-8)
        }
    }
    else{
        return -1;
    }
}

console.log(fn(40))

8.计算糖果

题目:
A,B,C三个人是好朋友,每个人手里都有一些糖果,我们不知道他们每个人手上具体有多少个糖果,但是我们知道以下的信息:
A - B, B - C, A + B, B + C. 这四个数值.每个字母代表每个人所拥有的糖果数.
现在需要通过这四个数值计算出每个人手里有多少个糖果,即A,B,C。这里保证最多只有一组整数A,B,C满足所有题设条件

输入例子:1 -2 3 4

输出例子:2 1 3

我的思路:一开始我是比较笨的才用分别利用输入的例子的每一个对应关系来写式子从而一个一个遍历判断,但其实经过观察可以发现A-B和A+B这两种情况相加后得出来的结果是2A,依次类推,后面就迎刃而解了

function fn(num){
    var A = (num[0]+num[2])/2;
    var B = (num[1]+num[3])/2;
    if(A.toString().split(".")[1]==undefined&&B.toString().split(".")[1]==undefined){
        var C = num[3]-B;
        return A+" "+B+" "+C
    }
    else{
        return "No"
    }
}

var num = [1,-2,3,4]
console.log(fn(num))

PS:有的题可能还有更好的解法,只是暂时还没想出来,主要就是那个跳石板怎么想都想不出来,希望有大神来帮忙解答哈哈^

阅读 5.4k

JavaScript
额。。该写什么呢,能不能啥都不写

这家伙很懒~啥都不愿意留下

454 声望
16 粉丝
0 条评论

这家伙很懒~啥都不愿意留下

454 声望
16 粉丝
文章目录
宣传栏