function clone(obj){ var result; switch(typeof obj){ case 'undefined': break; case 'string': result = obj+''; break; case 'number': result = obj-0; break; case 'boolean': result =obj; break; case 'object': if(obj ===null){ result = null; } else { if(Object.prototype.toString.call(obj).slice(8,-1)==='Array'){ result=[]; for(var i=0;i<obj.length;i++){ result.push(clone(obj[i])); } }else{ result=[]; for(var k in obj){ result[k]=clone(obj[k]); } } }; break; default: result = obj; break; } return result }
回文是指把相同的词汇或句子,在下文中调换位置或颠倒过来,产生首尾回环的情趣,叫作回文,也叫回环。前端
不少人拿到这样的题目很是容易想到用for将字符串颠倒字母顺序而后匹配就好了。其实重要的考察的是对于reverse的实现。其实咱们能够利用现成的函数,将字符串转换成数组,这个思路很重要,咱们能够拥有更多的自由度去进行字符串的一些操做。
let reverseStr = function(str) { return str = str.split('').reverse().join(''); } reverseStr('abcdefg'); //gfedcba
如fix this one 变为 one this fix。重点是检测到空格时进行处理。node
function reverseWord(str){ return str.split(' ').reverse().join(' ') }
“I am the good boy” 反转成这样 “I ma eht doog yob”面试
function reverse(str){ return str.split(' ').reverse().join(' ').split('').reverse().join(''); }
题目以下输入: [3,13,24,11,11,14,1,2]
输出: [3,13,24,11,14,2]
须要去掉重复的11 和 1 这两个元素。算法
这道题有多重方法,我理解的主要是考察我的对Object的使用,利用key来进行筛选。
function unique(arr) { let hashTable = {}; let data = []; for(let i=0,l=arr.length;i<l;i++) { if(!hashTable[arr[i]]) { hashTable[arr[i]] = true; data.push(arr[i]); } } return data } unique([3,13,24,11,11,14,1,2]) //[3,13,24,11,14,2]
再来一个其余实现方式,这个方法常在个人项目中出现,用的时候确实以为代码少了那么几行数组
function unique(arr) { let data = []; for(let i=0,l=arr.length;i<l;i++) { if(data.indexOf(arr[i])==-1) { data.push(arr[i]); } } return data } unique([3,13,24,11,11,14,1,2]) //[3,13,24,11,14,2]
输入一段英文连续的英文字符串 afjghdfraaaasdenas,找出重复出现次数最多的字母数据结构
function findMaxChar(str) { if(str.length == 1) { return str; } let charObj = {}; for(let i=0;i<str.length;i++) { if(!charObj[str.charAt(i)]) { charObj[str.charAt(i)] = 1; }else{ charObj[str.charAt(i)] += 1; } } return compare(charObj); }; function compare(charObj){ let maxChar = '', maxValue = 1; for(var k in charObj) { if(charObj[k] >= maxValue) { maxChar = k; maxValue = charObj[k]; } } return maxChar; } findMaxChar('afjghdfraaaasdenas') //a
遍历字符串,用一个对象当作hash表来存储重复字符。dom
function firstNonRepeatChar(str){ var count = {}; for(var i=0;i<str.length;i++){ if(count[str[i]]){ count[str[i]]++; }else{ count[str[i]] = 1; } } for(var prop in count){ if(count[prop] === 1){ return prop; } } }
实际上是在上一个问题的基础上再进行操做:ide
function firstNonRepeatChar(str){ var count = {}; var result = []; for(var i=0;i<str.length;i++){ if(count[str[i]]){ count[str[i]]++; }else{ count[str[i]] = 1; } } for(var prop in count){ if(count[prop] === 1){ result.push(prop); } } return result.join(''); }
Math.floor(Math.random()*(m-n))+n
冒泡排序JavaScript代码实现:函数
function bubbleSort(arr) { var len = arr.length; for (var i = 0; i < len; i++) { for (var j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j+1]) { //相邻元素两两对比 var temp = arr[j+1]; //元素交换 arr[j+1] = arr[j]; arr[j] = temp; } } } return arr; } bubbleSort([3,5,2,8,9,7,6]) //[2, 3, 5, 6, 7, 8, 9]
在时间复杂度上表现最稳定的排序算法之一,由于不管什么数据进去都是O(n²)的时间复杂度。。。因此用到它的时候,数据规模越小越好。惟一的好处可能就是不占用额外的内存空间了吧。
function selectionSort(arr) { var len = arr.length; var minIndex, temp; for (var i = 0; i < len - 1; i++) { minIndex = i; for (var j = i + 1; j < len; j++) { if (arr[j] < arr[minIndex]) { //寻找最小的数 minIndex = j; //将最小数的索引保存 } } temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; } return arr; } selectionSort([3,5,2,8,9,7,6]) //[2, 3, 5, 6, 7, 8, 9]
好比你有1到100的整数,而其中缺了一个,怎么找出这个数字?利用等差数列公式计算这些数应得的和,再计算当前数组全部数字的和,两者的差即为缺乏的数。测试
function missingNumber(arr){ var n = arr.length+1; var expectedSum = (1+n)*n/2; var sum = 0; for(var i=0;i<arr.length;i++){ sum+=arr[i]; } return expectedSum - sum; }
最暴力的方法就是两层循环,是O(n2).改进方法使用一个对象做为哈希表,用于存储数,这样在每次搜寻是否有另外一个数与当前数的和为sum时就能够在O(1)的时间内找到。
function twoSum(arr,sum){ var obj = {}; var num; for(var i=0;i<arr.length;i++){ num = sum - arr[i]; if(obj[num]){ return true; }else{ //若没有的话为当前数字创建索引 obj[arr[i]] = true; } } return false; }
最暴力的方法就是两层循环,是O(n2).改进方法使用一个对象做为哈希表,用于存储数,这样在每次搜寻是否有另外一个数与当前数的和为sum时就能够在O(1)的时间内找到。
function twoSum(arr,sum){ var obj = {}; var num; for(var i=0;i<arr.length;i++){ num = sum - arr[i]; obj[num]=arr.length+1; if(obj[num]){ obj[arr[i]]=i; obj[num]=arr.indexOf(num); return obj; }else{ //若没有的话为当前数字创建索引 obj[arr[i]] = i; } } return false; }
找到两个最大的数并返回它们的和。
function topSum(arr){ if(arr.length<2) return null; var first,second; if(arr[0]>arr[1]){ first = arr[0]; second=arr[1]; }else{ first = arr[1]; second=arr[0]; } for(var i=2;i<arr.length;i++){ if(arr[i]>first){ second = first; first = arr[i]; }else if(arr[i]>second){ second = arr[i]; } } return first+second; }
n=50的话,有5个0,分别是10,20,30,40,50。
n = 120的话,分别是10到90,共九个,110到120,共2个,以及100的两个,一共13个。
也就是说10的整数次方会有多个零,如100,1000,那么就要利用现有的数计算包含了多少个10的平方数。
如2014,2014/10=201; 201/10 = 20; 20/10 = 2; 最后代表出现了两次10的三次方,即1000和2000。
function countZero(n){ var count = 0; while(n>0){ count+=Math.floor(n/10); n/=10; } return count; }
function substr(str,subStr){ for(var i=0;i<str.length;i++){ for(var j=0;j<subStr.length;j++){ if(str[i+j] != subStr[j]){ break; } } if(j == subStr.length){ return i; } } return -1; }
var result = []; function permutations(str){ var arr= str.split(''); helper(arr,0,[]); return result; } function helper(arr,index,list){ if(index === arr.length){ result.push(list.join('')); return; } for(var i = 0;i<arr.length;i++){ if(list.indexOf(arr[i]) != -1){ continue; } list.push(arr[i]); helper(arr,index+1,list) list.pop(); } }
把 a = 2, b = 4 变成 a = 4, b =2
这种问题很是巧妙,须要你们跳出惯有的思惟,利用 a , b进行置换
主要是利用 + – 去进行运算,相似 a = a + ( b – a) 实际上等同于最后 的 a = b;
function swap(a , b) { b = b - a; a = a + b; b = a - b; console.log('a='+a); console.log('b='+b) } var a=2,b=4; swap(a,b) //a=4;b=2
斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、一、一、二、三、五、八、1三、2一、3四、……在数学上,斐波纳契数列主要考察递归的调用。
function getFibonacci(n) { var fibarr = []; var i = 0; while(i<n) { if(i<=1) { fibarr.push(i); }else{ fibarr.push(fibarr[i-1] + fibarr[i-2]) } i++; } return fibarr; } getFibonacci(9); //拿到9个 //[0、一、一、二、三、五、八、1三、21]
解法一:迭代
var fibonacci = function(n){ var fibo = [0,1]; for(var i=2;i<=n;i++){ fibo[i] = fibo[i-1]+fibo[i-2]; } return fibo[n]; }
解法二:递归
var fibonacci = function(n){ if(n>=2){ return fibonacci(n-1)+fibonacci(n-2); }else{ return n; } }
解法一:遍历
var greatestCommonDivisor= function(a,b){ if(a<2 || b<2) return 1; var divider = 2; var greatestDivisor = 1; while(divider<=a && divider<=b){ if(a%divider == 0 && b%divider == 0){ greatestDivisor = divider; } divider++; } return greatestDivisor; }
解法二:展转相除法
又名欧几里德算法(Euclidean algorithm)乃求两个正整数之最大公因子的算法。它是已知最古老的算法……
有解释的,但我选择不去理解……
function greatestCommonDivisor(a, b){ if(b == 0) return a; else return greatestCommonDivisor(b, a%b); }
var mergeSortedArray = function(a,b){ var merge = []; var i = 0,j = 0; var k = 0; while(i<a.length || j<b.length){ if(i == a.length || (j!=b.length && a[i]>b[j])){ merge[k++] = b[j++]; }else{ merge[k++] = a[i++]; } } return merge; }
质数只能被1和它本身整除,所以令被除数从2开始,若能整除则不是质数,若不能整除则加一,直到被除数到达根号n,此时n则是质数。
function isPrime(n){ var divider = 2; var limit = Math.sqrt(n); while(divider<=limit){ if(n%divider == 0){ return false; } divider++; } return true; } isPrime(3); //true
divider从2开始,若是n能整除divider,则将divider加入到结果中,n为这次计算后的商,若是n不能整除divider,则divider++
var primeFactors = function(n){ var factors = []; var divider = 2; while(n>2){ if(n%divider == 0){ factors.push(divider); n /= divider; }else{ divider++; } } return factors; }
这是经过一道题目去测试对于基本的数组的最大值和最小值的查找
function getMaxProfit(arr) { var minPrice = arr[0]; var maxProfit = 0; for (var i = 0; i < arr.length; i++) { var currentPrice = arr[i]; minPrice = Math.min(minPrice, currentPrice); var potentialProfit = currentPrice - minPrice; maxProfit = Math.max(maxProfit, potentialProfit); } return maxProfit; } getMaxProfit([10,5,11,7,8,9]) //6
function randomString(n) { let str = 'abcdefghijklmnopqrstuvwxyz9876543210'; let tmp = '', i = 0, l = str.length; for (i = 0; i < n; i++) { tmp += str.charAt(Math.floor(Math.random() * l)); } return tmp; } randomString(9); //指定长度为9 //4ldkfg9j7
本身实现一个函数,查找某个DOM节点下面的包含某个class的全部DOM节点?不容许使用原生提供的 getElementsByClassName querySelectorAll 等原生提供DOM查找函数。
function queryClassName(node, name) { var starts = '(^|[ \n\r\t\f])', ends = '([ \n\r\t\f]|$)'; var array = [], regex = new RegExp(starts + name + ends), elements = node.getElementsByTagName("*"), length = elements.length, i = 0, element; while (i < length) { element = elements[i]; if (regex.test(element.className)) { array.push(element); } i += 1; } return array; } queryClassName()
通常叫所有写完的几率比较少,可是重点考察你对它的理解和一些基本特色的实现。 二叉查找树,也称二叉搜索树、有序二叉树(英语:ordered binary tree)是指一棵空树或者具备下列性质的二叉树:
任意节点的左子树不空,则左子树上全部结点的值均小于它的根结点的值;
任意节点的右子树不空,则右子树上全部结点的值均大于它的根结点的值; 任意节点的左、右子树也分别为二叉查找树;
没有键值相等的节点。二叉查找树相比于其余数据结构的优点在于查找、插入的时间复杂度较低。为O(log
n)。二叉查找树是基础性数据结构,用于构建更为抽象的数据结构,如集合、multiset、关联数组等。
class Node { constructor(data, left, right) { this.data = data; this.left = left; this.right = right; } } class BinarySearchTree { constructor() { this.root = null; } insert(data) { let n = new Node(data, null, null); if (!this.root) { return this.root = n; } let currentNode = this.root; let parent = null; while (1) { parent = currentNode; if (data < currentNode.data) { currentNode = currentNode.left; if (currentNode === null) { parent.left = n; break; } } else { currentNode = currentNode.right; if (currentNode === null) { parent.right = n; break; } } } } remove(data) { this.root = this.removeNode(this.root, data) } removeNode(node, data) { if (node == null) { return null; } if (data == node.data) { // no children node if (node.left == null && node.right == null) { return null; } if (node.left == null) { return node.right; } if (node.right == null) { return node.left; } let getSmallest = function(node) { if(node.left === null && node.right == null) { return node; } if(node.left != null) { return node.left; } if(node.right !== null) { return getSmallest(node.right); } } let temNode = getSmallest(node.right); node.data = temNode.data; node.right = this.removeNode(temNode.right,temNode.data); return node; } else if (data < node.data) { node.left = this.removeNode(node.left,data); return node; } else { node.right = this.removeNode(node.right,data); return node; } } find(data) { var current = this.root; while (current != null) { if (data == current.data) { break; } if (data < current.data) { current = current.left; } else { current = current.right } } return current.data; } } module.exports = BinarySearchTree;
function getArrayMess(arr) { if(arr.length == 1) { console.log("{"+arr[0]+":1") } let charObj = {}; for(let i=0;i<arr.length;i++) { if(!charObj[arr[i]]) { charObj[arr[i]] = 1; }else{ charObj[arr[i]] += 1; } } console.log(charObj) }