9.17 滴滴前端笔试
题型:1.5h、选择题X20 + 编程X2
选择题:
考得有点杂,有数据库、Linux的东西,但是基础的html、css、js考察得比较简单。记几个印象比较深的吧!
- <img>、<table>哪个是语义化标签 —— table不是语义化标签
- jQuery里选择this的方法是 —— $(this),误导选项有$('this')
- 哪些排序算法是交换算法—— 冒泡排序和快速排序
编程题:
- 两道模拟题,思路很容易想到,但编程费点事情。供参考,不保证能AK
- 对于多个条件判断的情况要及时检验,如第2题,即写好一个就打印看看,有问题就及时解决,不然太乱了,都不知道问题出在哪里了
- 要多练习,不然光有思路也做不出来,第2题踩了一个坑,怎么判断都不对,如下面arr[index + 1] !== 1那里没考虑到,数组中的数据是字符串,即是‘1’,而不是1。所以要么提前把字符串转为数字,要么用“==”判断
// 处理头部的问号 if(item === '?' && index === 0) { if(arr[index + 1] == undefined || arr[index + 1] !== 1) { tempArr.push(1); } else if (arr[index + 1] === 1) { tempArr.push(2); } }
一、破译密码
发送方会对密码做如下加密,如欲发送y,会将y的二进制数中1的个数记为x,将加密后的数y*x发送出去,接收方拿到数据z后,进行解密,返回可能的原数据y。如接收到54054,解密后可能结果为[9009, 7722, 6006]。输出结果的个数和按从小到大的顺序的字符串即输出 3 6006 9009 7722
思路:
- 逆向暴力求解,即记原数据所乘的个数x为i,通过for循环i,得到原数据y,再去验证y变成二进制数据后1的个数是否为i,相等即可行。思路很简单,但是有一个问题,for循环i的范围是多少,我想的是慢慢试,比如1-50、不能AC就1-100…… 但是怎么试都只通过9%,后来才发现题目里要求结果按从小到大输出,吐血! 下面就默认i的范围是1-50
- 那么能不能确定下i的范围呢?还是希望这个范围能尽量小的。假如设原数据转二进制后1的个数为x,那么原数据最小为2^x-1即接收的值z >= x*(2^x-1),这个应该能得到x的范围,或者有没有其他方法?
function getRes(num) { let res = []; for(let i = 1; i < 11; ++i) { if(num % i === 0 && judgeI(num, i)) { res.push(num/i) } } console.log(res.length); console.log(res.sort().join(' ')); } function judgeI(num, i) { let origin = num/i, count = 0 // 将原来的数转成二进制 let arr = [...origin.toString(2)]; arr.map(i => {if(i == '1'){count++}}) return count == i? true:false; } getRes(54054); // 3 6006 7722 9009
二、恢复被墨水污染的实验数据
即一串非负正整数数字,其中部分位数被墨水污染了记为‘?’,但是该数据符合以下的规则。要求将数据恢复,并使得数据最小。例如输入'?12?0?9??',输出'212101902'。
- 首位不能是0;
- 相邻数字不相同
- 这个数可以被3整除
思路:
- 用map遍历原字符串数组,遇到‘?’就看看给个最合适的且最小的值,记住最后一个"?"除了不能和两边的相同,而且还要保证该数可以被3整除。为啥要最后一个保3呢?因为要求数据最小,所以高位数据尽量小,最后一位在“保3”的基础上尽量小!
- 一个数能被3整除的充要条件是它各位之和也要能被3整除
- 下面函数的输入已经将字符变为数组了
function getRes(arr) { // 最后一个的序号要用它“保三” let lastIndex = arr.lastIndexOf("?"); let tempArr = []; arr.map((item, index) => { // 处理头部的问号 if(item === '?' && index === 0) { if(arr[index + 1] == undefined || arr[index + 1] != 1) { arr[index] = 1; } else if (arr[index + 1] == 1) { arr[index] = 2; } } else if(item === '?' && index < lastIndex) { // 处理中间的'?' for(let i = 0; i <= 9; ++i) { if(arr[index - 1] != i && arr[index + 1] != i) { arr[index] = i; // 找到一个就跳出 break; } } } else if (index === lastIndex) { // 处理最后的问号,要复杂一点 // 先求出除最后一个"?"外所有的值和 let sum = 0; arr.forEach((element) => { if (element !== "?") sum += parseInt(element); }); for (let i = 0; i <= 9; ++i) { if ( arr[index - 1] != i && (arr[index + 1] == null || arr[index + 1] != i) ) { console.log(sum); // 看能不能'保三' if ((sum + i) % 3 === 0) { arr[index] = i; // 找到一个就跳出循环 break; } } } } } ) return arr.join(""); } console.log(getRes(["?", "1", "2", "?", "0", "?", "9", "?", "?"]));