前段時間換了份工作,也經歷了很多面試,最終通常都會撲在演算法上
雖說前端是所有程式設計師中,對於演算法的要求最低的一個崗位,但演算法依舊是進階的必修課
於是決定記錄一下與演算法相關的面試題,以後拿去面別人
一、面試題
問:有一個一百層的高樓,現在給你兩個完全一樣的玻璃球,去測出在哪一層樓把球扔出去,剛好能把玻璃球砸碎?
答: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. 如果只有兩個球,怎麼才能用最少的次數,找到臨界點?