上星期四去腾讯面试前端开发,一上来就是一份算法的笔试题,有六道,因为太久没做算法题了,有点错愕慌张,写的比较杂乱,回来之后整理了一下思绪。
第一道题【有52张牌,请设计一个方法把他们尽可能的打乱,不要让牌出现在原来的位置】
本题答主,没有答,因为对题面不是非常理解,难道把牌都往右或往左移N(n!=52)个位置让牌不在原来的位置就可以了?
代码如下:
1 function Rand(arr) { 2 var arr2 = []; 3 for (var i = 0; i < arr.length; ++i) { 4 var temp; 5 do temp = Math.ceil(Math.random() * arr.length); 6 while (arr2[temp] != undefined); 7 arr2[temp] = i; 8 } 9 return arr2; 10 }
第二道题【有一个方法Rand5(),可以得到[0,5)的随机一个整数,请利用这个方法写一个Rand3()方法,得到[0,3)的随机一个整数,概率需要相同,不能用其他的随即函数】
本题答主过虑了,考虑到原本的Rand5()是不是在获取[0,1,2,3,4]的时候概率是不一样的,是不是4的概率高一点而0的概率低一点之类的,之后跟朋友聊起,他们都说你想太多了,既然他给你这个方法,那么肯定得到几个整数的概率是相等的。
然后假想一下,那么如果Rand5()得到五个整数的概率是一样的,那么直接
1 function Rand3() { 2 var num; 3 while ((num = Rand5()) >= 3);
4 return num; 5 }
只需要忽略忽略大于3的整数,就可以了?因为返回的时候也是等概率的1/5;
那么,如果是不等概率的情况下呢?
待思考…………
第三道题【把1到n-1放在长度为n的数组N里面,请找出重复的那个数字,要求时间复杂度为O(n),空间复杂度为O(n)】
这道题当时答主头脑发昏了竟然没做,其实思路非常明显。
假设数组本身是已经排好序的,连对数组排序都不用,直接查下标就可以了。
代码如下:
1 function check(arr) { 2 for (var i = 0; i < arr.length; ++i) { 3 if (i + 1 != arr[i]) return arr[i]; 4 } 5 }
假设数组本身是杂乱没有排序的,那么
代码如下:
1 function check(arr) { 2 var arr2 = []; 3 for (var i = 0; i < arr.length; ++i) { 4 var temp = arr2[arr[i]]; 5 if (temp == undefined) arr2[arr[i]] = 1; 6 else return arr[i]; 7 } 8 }
第四道题【对称数121,12321等,请写一个方法验证一个数是否为对称数,不能转换为字符串处理】
这道题答主整个看下来没什么限制,也没用去考虑有没有最优的作法,直接暴力拆成数组解决,由于能传参进来的数字不会是大数。
代码如下:
1 function symmetry(num) { 2 var arr = []; 3 while (num >= 10) { 4 arr.push(num % 10); 5 num = Math.floor(num / 10); 6 } 7 arr.push(num); 8 for (var i = 0; i < arr.length - i - 1; ++i) { 9 if (arr[i] != arr[arr.length - i - 1]) return 0; 10 } 11 return 1; 12 }
第五道题【请写一个方法,统计一个整数中有多少个0】
这道题没有过多的限制,答主也没有多想,直截了当的按上一题的解法解决了。(后来答主才发现遗漏了要先取绝对值这一步……= =!!!)
代码如下:
1 function zero(num) { 2 num = Math.abs(num); //遗漏的就是这一步 3 if (num == 0) return 1; 4 var sum = 0; 5 while (num >= 10) { 6 if (num % 10 == 0) sum++; 7 num = Math.floor(num / 10); 8 } 9 return sum; 10 }
第六道题【有一个二叉树,请写一个方法,验证是否存在一条路径从根节点到某个叶子节点,数值加起来等于value,存在返回1,不存在返回0】
题目规定的节点结构体为
1 struct node { 2 node * LeftChild; 3 node * RightChild; 4 int value; 5 }
没有指向parent的指针= =!!!
此题答主认为就是遍历二叉树、路径查找。可以用递归和非递归解决。
递归代码如下:
1 function recursion(node, value) { 2 value -= node.value; 3 var result = 0; 4 if (node.LeftChild != null) result = recursion(node.LeftChild, value); 5 if (!result && node.RightChild != null) result = recursion(node.RightChild, value); 6 if (node.LeftChild == null && node.RightChild == null && value == 0) result = 1; 7 else if(node.LeftChild == null && node.RightChild == null && value != 0) result = 0;
8 return result;
9 }
非递归代码如下:
其实就是加个任务队列,不贴出来了~~~