腾讯面试笔试题

  上星期四去腾讯面试前端开发,一上来就是一份算法的笔试题,有六道,因为太久没做算法题了,有点错愕慌张,写的比较杂乱,回来之后整理了一下思绪。

  第一道题【有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 }

  非递归代码如下:

  其实就是加个任务队列,不贴出来了~~~

原文地址:https://www.cnblogs.com/kirachen/p/4626603.html