前端面試(演算法篇) – 二分法

Wise.Wrong發表於2018-08-15

前段時間換了份工作,也經歷了很多面試,最終通常都會撲在演算法上

雖說前端是所有程式設計師中,對於演算法的要求最低的一個崗位,但演算法依舊是進階的必修課

於是決定記錄一下與演算法相關的面試題,以後拿去面別人

 

一、面試題

問:有一個一百層的高樓,現在給你兩個完全一樣的玻璃球,去測出在哪一層樓把球扔出去,剛好能把玻璃球砸碎?

答:emmmmmm

問:球碎了就沒法用了

答:那如果沒碎呢?

問:emmmmmm

答:啊哈,那就拿著球從一樓往上,一層一層的試唄~

問:好,那現在不限制球的數量,但要求用最少的次數,去找到這個臨界點

答:二分法!從中間的樓層開始扔球,如果碎了就在下面的樓層中繼續找

問:沒錯,二分法是最快的解決方案,但如果遇到最差的情況,需要用幾個球呢?

答:我數一數

問:……

答:……

問:算了,下一個問題吧

 

二、二分法

使用二分法的前提是,目標陣列的元素必須是有序排列的,所以二分法屬於有序查詢演算法

二分法又稱為“折半查詢”,從陣列的中間節點開始查詢,將陣列分為兩部分

如果目標元素和中間節點不相等,就通過比較兩者的大小,確定接下來查詢陣列的前半部分還是後半部分

然後遞迴查詢,直到找到目標元素,或者發現目標元素不在陣列內

在最壞的情況下,需要的次數為:(logn)+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. 如果只有兩個球,怎麼才能用最少的次數,找到臨界點?

 

相關文章