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) }