關於去重等等一系列

let arr = [ [ ['1-7', '2-6'], '4-6', [ ['2-0', '1-4'], ['3-9'], '4-5', ], ] ]面試

// Q1: 完成數組 flat 函數 function flat(arr) { // code return arr }算法

arr = flat(arr); console.log(arr);數組

// Q2: 計算 arr 中全部的值:'1-7' => 1 * 7 = 7, 返回一個數字組成的數組 function calc(arr) { // code return arr; }緩存

arr = calc(arr); console.log(arr);數據結構

// Q3: 對這個數組排序和去重 function sortAndReduce(arr) { // code return arr; }閉包

arr = sortAndReduce(arr); console.log(arr);函數

數組 Flat 時間回溯 這個數組結構比較深,這應該是整個題目的考點所在。看這個樣子應該是須要用遞歸,不!應該還有更好的方法,那就使用ES 2019 的 Array.prototype.flat 函數吧!而後被面試官一票否決。在塗塗改改和思考的時間中,面試官問了個人思路結束了這個問題。 方案1: 遞歸 若是有對遞歸不太熟悉的同窗,能夠看看個人讀書筆記【算法圖解】讀書筆記:第3章 遞歸。 遞歸的核心就在於兩步:找到基線條件和遞歸條件。 function flat(arr) { const result = []; // 利用閉包緩存咱們的結果 function _flat(arr) { arr.forEach(element => { if(Array.isArray(element)) { // 遞歸條件 _flat(element); } else { // 基準條件 result.push(element); // 將符合結果的值推入咱們的結果數組中 } }) } _flat(arr); arr = result; return arr; }性能

// 更加簡練的版本prototype

const flat = arr => [].concat(...arr.map(v => Array.isArray(v) ? flat(v) : v)); 複製代碼方案2: 迭代 - 廣度優先搜索 這個思路是我借鑑《圖解算法》中廣度優先搜索算法章節寫的。code

建立一個數組,保存結果 建立一個隊列 初始化 使用 while 循環去遍歷 list 裏面的每一項 將第一項推出隊列

若是是數組,將子項依次推入隊列 若是是字符串,將子項推入結果

當 list 長度爲0時候,遍歷完成

可是廣度優先搜索的結果是不保證順序的。

參考書籍:《圖解算法》 不推薦的筆記,沒書能夠看看【算法圖解】讀書筆記:第6章 廣度優先搜索

function flat(arr) { const result = []; // 儲存結果 const list = []; // 隊列 function _forEach(arr) { arr.forEach(el => { if(Array.isArray(el)) list.push(el); // item 若是是數組,將子項依次推入隊列 else result.push(el); // item 若是是字符串,將子項推入結果 }); } _forEach(arr); // 初始化 while(list.length > 0) { // 當 list 長度爲0時候,遍歷完成 const item = list.shift(); _forEach(item); }

上面兩個方法只是個人拙見,但願能夠在評論區看見更好更優秀的算法

方案3: 投機取巧的 toString 們

// 首頁你得肯定你的數據裏面沒有字符串 ',' 哦 function flat(arr) { arr = arr.toString().split(',') return arr; }

// or // 殊途同歸 function flat(arr) { arr = arr.join(',').split(',') return arr; } 迭代 - 深度優先搜索 感謝 @IWANABETHATGUY 同窗的賜教。 原理與廣度優先搜索相似,經過模擬棧的行爲去遍歷數組。好處是可以保證有序輸出。 function flat(arr) { let result = []; let stack = []; // 模擬棧的行爲

function forEachRight(arr) { for (let i = arr.length - 1; i >= 0; i--) { // 先進後出 const item = arr[i]; if(Array.isArray(item)) stack.push(item); else result.push(item); } } if (arr.length > 0) forEachRight(arr); while (stack.length > 0) { // 當棧空了,遍歷完成 let current = s.pop(); if(current.length > 0) { forEachRight(current); // 感謝 @Drowned-fish 朋友的建議 } } return ret; } 數組計算 '1-7' => 1 * 7 = 7 這個問題難度不大,就是考察一些經常使用方法的使用,直接上代碼。 function calc(arr) { // 隨手騷一下,不建議 eval arr = arr.map(el => eval(el.replace('-', '*'))); return arr; }

// or

function calc(arr) { arr = arr.map(el => { const [n1, n2] = el.split('-'); return +n1 * +n2; }); return arr; }

Q3: 數組排序和去重 數組去重能夠經過 ES6 的 Set 完成。傳送門:ES6 Set 數據結構,不做贅述。數組排序可使用 Array.prototype.sort 函數實現。可是顯然考察算法內容,不能直接使用原生方法,並且排序和去重同時完成,性能確定更好。 我以前寫過一篇常規的幾種排序方法的對比和實現,【JS面試向】選擇排序、桶排序、冒泡排序和快速排序簡介,這裏我直接使用快速排序完成排序和去重工做。 function sortAndReduce(arr) { if(arr.length < 2) { return arr; } else { const pivot = arr[0]; // 基準值 const lowArr= []; // 小的放左邊 const hightArr = []; // 大的放右邊 arr.forEach(current => { if(current > pivot) hightArr.push(current); else if(current < pivot) lowArr.push(current); }) return sortAndReduce(lowArr).concat(pivot, sortAndReduce(hightArr)); } }

相關文章
相關標籤/搜索