Q1 判断一个单词是否是回文?
回文是指把相同的词汇或句子,在下文中调换位置或颠倒过来,产生首尾回环的情趣,叫做回文,也叫回环。比如 mamam redivider .
很多人拿到这样的题目非常容易想到用for 将字符串颠倒字母顺序然后匹配就行了。其实重要的考察的就是对于reverse的实现。其实我们可以利用现成的函数,将字符串转换成数组,这个思路很重要,我们可以拥有更多的自由度去进行字符串的一些操作。
function checkPalindrom(str) {
return str == str.split('').reverse().join('');
}
console.log(checkPalindrom('mamam')); //true
console.log(checkPalindrom('banana')); //false
split() 方法用于把一个字符串分割成字符串数组。
reverse() 方法用于颠倒数组中元素的顺序。
join() 方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。
Q2 去掉一组整型数组重复的值
比如 输入: [1,13,24,11,11,14,1,2], 输出: [1,13,24,11,14,2] ,需要去掉重复的11 和 1 这两个元素。
主要考察个人对Object的使用,利用key来进行筛选。
let unique = function(arr) {
let hashTable = {};
let data = [];
for(let i=0,l=arr.length;i if(!hashTable[arr[i]]) { hashTable[arr[i]] = true; data.push(arr[i]); } } return data } var arr=[1,13,24,11,11,14,1,2] console.log(unique(arr)) //[1, 13, 24, 11, 14, 2] 还有一种方法 利用ES6的Set var arr=[1,13,24,11,11,14,1,2]; let uniqueES6= function(arr){ return Array.from(new Set(arr)) } console.log(uniqueES6(arr))//[1, 13, 24, 11, 14, 2] Q3 统计一个字符串出现最多的字母 给出一段英文连续的英文字符窜,找出重复出现次数最多的字母 比如: 输入:afjghdfraaaasdenas 输出 : a 前面出现过去重的算法,这里需要是统计重复次数。 function findMaxDuplicateChar(str){ if(str.length == 1){ return str } let charObj ={} for(let i=0;i if(!charObj[str.charAt(i)]){ charObj[str.charAt(i)] = 1; }else{ charObj[str.charAt(i)] +=1; } } let maxchar = '', maxvalue=1; for(var k in charObj){ if(charObj[k] >= maxvalue){ maxchar =k; maxvalue=charObj[k]; } } return maxchar; } console.log(findMaxDuplicateChar('gffhghjllyesdfffnmfffssssffffjjffff')) //f Q4 排序算法 如果说到算法题目的话,应该大多都是比较开放的题目,不限定算法的实现,但是一定要求掌握其中的几种。 冒泡排序 插入排序 快速排序 选择排序 let arr = [4,6,32,11,5,667,39,56,78,2,42,7]; /*冒泡排序*/ function bubbleSort(arr){ for(var i=0;i for(var j=0;j if(arr[j]>arr[j+1]){ var temp = arr[j] arr[j] = arr[j+1] arr[j+1] = temp } } } return arr } console.log(bubbleSort(arr)) /*插入排序*/ function insertionSort(array) { console.time('插入排序耗时:'); for (var i = 1; i < array.length; i++) { var key = array[i]; var j = i - 1; while ( array[j] > key) { array[j + 1] = array[j]; j--; } array[j + 1] = key; } console.timeEnd('插入排序耗时:'); return array; } console.log(insertionSort(arr)); /*快速排序*/ function quickSort(arr){ //如果数组<=1,则直接返回 if(arr.length<=1){return arr;} var pivotIndex=Math.floor(arr.length/2); //找基准,并把基准从原数组删除 var pivot=arr.splice(pivotIndex,1)[0]; //定义左右数组 var left=[]; var right=[]; //比基准小的放在left,比基准大的放在right for(var i=0;i if(arr[i]<=pivot){ left.push(arr[i]); } else{ right.push(arr[i]); } } //递归 return quickSort(left).concat([pivot],quickSort(right)); } console.log(quickSort(arr)) // 选择排序 var arr = [8,3,9,12,45,23,4,89,48,63,27,53,56,98] function selectSort(arr){ var len = arr.length for(var i= 0;i for(var j = i+1;j if(arr[i]>arr[j]){ var temp = arr[i] arr[i] = arr[j] arr[j] = temp } } } return arr } console.log(selectSort(arr)) // 选择排序的思想是:把每一个数都与第一个数比较,如果小于第一个数,就把它们交换位置;这样一轮下来,最小的数就排到了最前面;重复n-1轮,就实现了选择排序 // 选择排序和冒泡排序思想上有些相近 十大经典排序算法总结(java代码) Q5 不借助临时变量,进行两个整数的交换 举例:输入 a = 2, b = 4 输出 a = 4, b =2 这种问题非常巧妙,需要大家跳出惯有的思维,利用 a , b进行置换。 主要是利用 + - 去进行运算,类似 a = a + ( b - a) 实际上等同于最后 的 a = b; let a=2 ,b=4 function swap(a , b) { b = b - a; a = a + b; b = a - b; return [a,b]; } console.log(swap(a , b)); Q6 使用canvas 绘制一个有限度的斐波那契数列的曲线 斐波那契数列曲线 数列长度限定在10. 斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列主要考察递归的调用。我们一般都知道定义 fibo[i] = fibo[i-1]+fibo[i-2]; var canvas = document.querySelector('canvas'); canvas.width = 600; canvas.height = 480; var coor = { x: 300, y: 240, }; var ctx = canvas.getContext('2d'); function draw(r, n ,prevR) { if(n>2) { switch(n%4) { case 0 : coor.y = coor.y - 5 * prevR; coor.y = coor.y + 5 * r; break; case 1 : coor.x = coor.x + 5 * prevR; coor.x = coor.x - 5 * r; break; case 2 : coor.y = coor.y + 5 * prevR; coor.y = coor.y - 5 * r; break; case 3 : coor.x = coor.x - 5 * prevR; coor.x = coor.x + 5 * r; break; } } ctx.beginPath(); ctx.arc(coor.x,coor.y,5*r,Math.PI*0.5*(n),Math.PI*0.5*(n-1),true); if(n>1) { switch(n%4) { case 0 : ctx.moveTo(coor.x - 5*r,coor.y); break; case 1 : ctx.moveTo(coor.x,coor.y + 5*r); break; case 2 : ctx.moveTo(coor.x + 5*r,coor.y); break; case 3 : ctx.moveTo(coor.x,coor.y-5*r); break; } } ctx.lineWidth = 1; ctx.strokeStyle = '#fff'; ctx.stroke(); } /*生成斐波那契数组的方法*/ function getFibonacci(n) { var fibarr = []; var i = 0; while(i if(i<=1) { fibarr.push(i); }else{ fibarr.push(fibarr[i-1] + fibarr[i-2]) } i++; } return fibarr; } console.log(getFibonacci(10)) //[0, 1, 1, 2, 3, 5, 8, 13, 21, 34] var data = getFibonacci(10); for(var i = 0,l=data.length;i if(data[i]!=0) { draw(data[i],i,data[i-1]); } } Q7 找出下列正数组的最大差值 比如: 输入 [10,5,11,7,8,9] 输出 6 这是通过一道题目去测试对于基本的数组的最大值的查找,很明显我们知道,最大差值肯定是一个数组中最大值与最小值的差。 var arr = [16,5,111,7,21,9] function getMaxProfit(arr) { const item1 = Math.max.apply( null, arr ); const item2 = Math.min.apply( null, arr ); return item1 - item2; } console.log(getMaxProfit(arr)) //106 ES6的方法 var arr = [16,5,111,7,21,9] //ES6 function getMaxProfitES6(arr){ const item1 = Math.max(...arr); const item2 = Math.min(...arr); return item1 - item2; } console.log(getMaxProfitES6(arr)); Q8 随机生成指定长度的字符串 实现一个算法,随机生成指制定长度的字符窜。 比如:给定 长度 8 输出 4ldkfg9j function randomString(n) { let str = 'abcdefghijklmnopqrstuvwxyz9876543210'; let tmp = '', l = str.length; for (let i = 0; i < n; i++) { tmp += str.charAt(Math.floor(Math.random() * l)); } return tmp; } console.log(randomString(8)) Q9 计算一个整数的阶乘 function factorialize(num) { if(num<1){ return 1; }else{ return num*factorialize(num-1); } } console.log(factorialize(5)); //120 Q10 找到提供的句子中最长的单词,并计算它的长度 function findLongestWord(str) { //转化成数组 var astr=str.split( " " ); //对数组中每个元素的字符串长度进行比较,按照字符串长度由大至小排列数组顺序。 var bstr=astr.sort(function(a,b){ return b.length-a.length; }); //取出数组中第一个元素(也就是最大长度的字符串) console.log(bstr[0]) //jumped var lenMax= bstr[0].length; //返回长度值 return lenMax; } console.log(findLongestWord("The quick brown fox jumped over the lazy dog"));//6 array.sort()方法默认是升序排序,如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下: 若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。 若 a 等于 b,则返回 0。 若 a 大于 b,则返回一个大于 0 的值。 简单点:比较函数两个参数a和b,返回a-b升序,返回b-a降序 Q11 确保字符串的每个单词首字母都大写,其余部分小写。 function titleCase(str) { var astr=str.toLowerCase().split(" "); for(var i=0 ; i astr[i]=astr[i][0].toUpperCase()+astr[i].substring(1,astr[i].length); } var string=astr.join(" "); return string; } console.log(titleCase("I'm a little tea pot"));//结果:I'm A Little Tea Pot Q12 找出4个小数组中最大值,组成一个新数组 function largestOfFour(arr) { var newArr=[]; for(i=0;i arr[i].sort(function(a,b){ return b-a; }); newArr.push(arr[i][0]); } return newArr; } console.log(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]])); //[5,27,39,1001] Q13 比较两个数组,然后返回一个新数组,该数组的元素为两个给定数组中所有独有的数组元素。换言之,返回两个数组的差异。 方法一: function diff(arr1, arr2) { var newArr = []; //过滤数组1中与数组2相等的项 var arr1Filtered=arr1.filter(function(num){ for(var i=0; i if(num==arr2[i]){ return false; } } return true; }); //过滤数组2中与数组1相等的项 var arr2Filtered=arr2.filter(function(num){ for(var i=0; i if(num==arr1[i]){ return false; } } return true; }); //连接两个数组 newArr=arr1Filtered.concat(arr2Filtered); return newArr; } var arr1 = [1, "calf", 3, "piglet"], arr2 = [1, "calf", 3, 4] console.log(diff(arr1, arr2)); // ["piglet", 4] 方法二: var arr1 = [1, "calf", 3, "piglet"], arr2 = [1, "calf", 3, 4] function fn(arr1,arr2){ var newArr = [] var arr1Filtered = arr1.filter(function(num){ if(arr2.indexOf(num)!=-1){ return false } return true }) var arr2Filtered = arr2.filter(function(num){ if(arr1.indexOf(num)!=-1){ return false } return true }) return arr1Filtered.concat(arr2Filtered) } console.log(fn(arr1,arr2)) Q14 写一个 function,传入两个或两个以上的数组,返回一个以给定的原始数组排序的不包含重复值的新数组。 说明:所有数组中的所有值都应该以原始顺序被包含在内,但是在最终的数组中不包含重复值。 如:unite([1, 3, 2], [5, 2, 1, 4], [2, 1]) 应该返回 [1, 3, 2, 5, 4]。 unite([1, 2, 3], [5, 2, 1, 4], [2, 1], [6, 7, 8]) 应该返回 [1, 2, 3, 5, 4, 6, 7, 8]。 方法一: function unite(arr1, arr2, arr3) { for(var j=1; j //过滤掉第j个数组中已经在前面出现过的值 var filteredArr=arguments[j].filter(function(num){ for(var i=0; i if(arr1[i]==num){ return false; } } return true; }); arr1=arr1.concat(filteredArr); } return arr1; } console.log(unite([1, 2, 3], [5, 2, 1, 4], [2, 1], [6, 7, 8])); //[1,2,3,5,4,6,7,8] 方法二: function unite(){ var arr = arguments[0] for(let i = 0;i var filterArr = arguments[i].filter(function(num){ if(arr.indexOf(num)!=-1){ return false } return true }) arr= arr.concat(filterArr) } return arr } console.log(unite([1, 2, 3], [5, 2, 1, 4], [2, 1], [6, 7, 8])); Q15 求小于等于给定数值的质数(素数)之和。 说明:只有 1 和它本身两个约数的数叫质数。例如,2 是质数,因为它只能被 1 和 2 整除。1 不是质数,因为它只能被自身整除。给定的数不一定是质数。 如:sumPrimes(10) 应该返回 17。 function sumPrimes(num) { //将所有小于等于num的质数放进一个数组 var arr=[]; //1不是质数,从2开始循环,需算上num for(var i=2; i<=num; i++){ var j=2; //判断i能否被从2开始的数整除 while(i%j!==0){ j++; } //判断这个数是不是自身,是则加进数组 if(i==j){ arr.push(i); } } //对数组求和 var result=arr.reduce(function (a,b){return a+b;}); return result; } console.log(sumPrimes(10)) ///17 reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。 reduce() 可以作为一个高阶函数,用于函数的 compose。 注意: reduce() 对于空数组是不会执行回调函数的。 另外一种写法 function sumFun(num){ let sum=0 for(let i=2;i<=num;i++){ var j= 2 while(i%j !==0){ j++ } if(j==i){ sum+=j } } return sum } console.log(sumFun(11)) //18 方法三 function getPrimes(n){ var arr = [] for(var i=2;i<=n;i++){ var flag = true for(var j = 2;j<=Math.sqrt(i);j++){ if(i%j==0){ flag = false break } } if(flag){ arr.push(i) } } //对数组求和 var result=arr.reduce(function (a,b){return a+b;}); return result } 方法四 function getPrimes(n){ var prime = [] var arr = [] for(var i = 2;i<=n;i++){ if(!prime[i]){ arr.push(i) for (var j = i; j*i <=n; j++) { prime[j*i]=true; } } } //对数组求和 var result=arr.reduce(function (a,b){return a+b;}); return result } Q16 写一个 function,它浏览数组(第一个参数)并返回数组中第一个通过某种方法(第二个参数)验证的元素。 如:find([1, 3, 5, 8, 9, 10], function(num) { return num % 2 === 0; }) 应该返回 8。 find([1, 3, 5, 9], function(num) { return num % 2 === 0; }) 应该返回 undefined。 function find(arr, func) { var newArr=arr.filter(func); return newArr[0]; } console.log(find([1, 3, 5, 8, 9, 10], function(num) { return num % 2 === 0; })) //8 Q17 对嵌套的数组进行扁平化处理。你必须考虑到不同层级的嵌套。 如:steamroller([1, [2], [3, [[4]]]]) 应该返回 [1, 2, 3, 4]。 steamroller([1, [], [3, [[4]]]]) 应该返回 [1, 3, 4]。 steamroller([1, {}, [3, [[4]]]]) 应该返回 [1, {}, 3, 4]。 1、 function steamroller(arr) { var newArr=[]; for(var i=0; i if(!Array.isArray(arr[i])){ newArr.push(arr[i]); }else{ newArr=newArr.concat(steamroller(arr[i])); } } return newArr; } console.log(steamroller([1, {}, [3, [[4]]]])) //[1, {}, 3, 4] 此题的解法是在一个for循环中使用了递归,在for循环中使用递归时,不会影响for循环的进程。 2、另外一种方法: function flatten(arr){ while(arr.some(item=>Array.isArray(item))){ arr = [].concat(...arr) } return arr; } console.log(flatten([1, {}, [3, [[4]]]]));//[1, 2, 3] some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。 some() 方法会依次执行数组的每个元素: 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。 如果没有满足条件的元素,则返回false。 注意:some() 不会对空数组进行检测。 注意:some() 不会改变原始数组。 3、es6新增的数组实例方法flat() [1, 2, [3, 4]].flat() // [1, 2, 3, 4] flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1。 [1, 2, [3, [4, 5]]].flat() // [1, 2, 3, [4, 5]] [1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5] 如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数。 [1, [2, [3]]].flat(Infinity) // [1, 2, 3] 如果原数组有空位,flat()方法会跳过空位。 [1, 2, , 4, 5].flat() // [1, 2, 4, 5] 4、如果数组中元素都是字符串,可以利用数组toString()方法 例如:['a',[b],c,[[d],e,[f,[g,h]]]] var arr= ['a',[`b`],`c`,[[`d`],`e`,[`f`,[`g`,`h`]]]] console.log(arr.toString().split(',')) Q18 二分查找 function binary_search(arr, key) { var low = 0, high = arr.length - 1; while(low <= high){ var mid = parseInt((high + low) / 2); if(key == arr[mid]){ return mid; }else if(key > arr[mid]){ low = mid + 1; }else if(key < arr[mid]){ high = mid -1; } } return -1; }; var arr=[2,4,6,9,11,25,28,36,44,47,67,76,79], key=36; console.log(binary_search(arr,key)) //7 因为二分查找每次排除掉一半的不适合值,所以对于n个元素的情况: 一次二分剩下:n/2 两次二分剩下:n/2/2 = n/4 …… m次二分剩下:n/(2^m) 在最坏情况下是在排除到只剩下最后一个值之后得到结果,所以为 n/(2^m)=1; 2^m=n; 所以时间复杂度为:log2(n) 作者:指尖跳动 链接:https://www.jianshu.com/p/2f38ac50c63a 来源: 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。