前段時間換了份工作,也經歷了很多面試,最終通常都會撲在演算法上 雖說前端是所有程式員中,對於演算法的要求最低的一個崗位,但演算法依舊是進階的必修課 於是決定記錄一下與演算法相關的面試題,以後拿去面別人 一、面試題 問:有一個一百層的高樓,現在給你兩個完全一樣的玻璃球,去測出在哪一層樓把球扔出去,剛好能把玻璃 ...
前段時間換了份工作,也經歷了很多面試,最終通常都會撲在演算法上
雖說前端是所有程式員中,對於演算法的要求最低的一個崗位,但演算法依舊是進階的必修課
於是決定記錄一下與演算法相關的面試題,以後拿去面別人
一、面試題
問:有一個一百層的高樓,現在給你兩個完全一樣的玻璃球,去測出在哪一層樓把球扔出去,剛好能把玻璃球砸碎?
答:emmmmmm
問:球碎了就沒法用了
答:那如果沒碎呢?
問:emmmmmm
答:啊哈,那就拿著球從一樓往上,一層一層的試唄~
問:好,那現在不限制球的數量,但要求用最少的次數,去找到這個臨界點
答:二分法!從中間的樓層開始扔球,如果碎了就在下麵的樓層中繼續找
問:沒錯,二分法是最快的解決方案,但如果遇到最差的情況,需要用幾個球呢?
答:我數一數
問:……
答:……
問:算了,下一個問題吧
二、二分法
使用二分法的前提是,目標數組的元素必須是有序排列的,所以二分法屬於有序查找演算法
二分法又稱為“折半查找”,從數組的中間節點開始查找,將數組分為兩部分
如果目標元素和中間節點不相等,就通過比較兩者的大小,確定接下來查找數組的前半部分還是後半部分
然後遞歸查找,直到找到目標元素,或者發現目標元素不在數組內
在最壞的情況下,需要的次數為:(log2 n)+1 ,其中 log2n 向下取整
function BinarySearch(arr, target) { let s = 0; let e = arr.length - 1; let m = Math.floor((s + e) / 2); let trun = arr[s] <= arr[e]; //確定排序順序 while (s < e && arr[m] !== target) { if (arr[m] > target) { trun ? (e = m - 1) : (s = m + 1) } else { trun ? (s = m + 1) : (e = m - 1) } m = Math.floor((s + e) / 2); } if (arr[m] == target) { console.log('找到了,位置%s', m, t); return m; } else { console.log('沒找到', t); return -1; } }
三、問題拓展
1. 用二分法遇到最壞的情況,需要 6 次 還是 7 次?
2. 如果只有兩個球,怎麼才能用最少的次數,找到臨界點?