1. 程式人生 > >一道簡單的面試題:竟然有90%的程式設計師不能把這個演算法完全寫正確。。。

一道簡單的面試題:竟然有90%的程式設計師不能把這個演算法完全寫正確。。。

前段時間,在論壇上看到有統計說有90%的程式設計師不能夠寫對簡單的二分法。二分法不是很簡單的嗎? 這難道不是聳人聽聞?

其實,二分法真的不那麼簡單,尤其是二分法的各個變種。 最最簡單的二分法,就是從一個排好序的陣列之查詢一個key值。 如下面的程式。


/**
 * 二分查詢,找到該值在陣列中的下標,否則為-1
 */
static int binarySerach(int[] array, int key) {
    int left = 0;
    int right = array.length - 1;

    // 這裡必須是 <=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (array[mid] == key) {
            return mid;
        }
        else if (array[mid] < key) {
            left = mid + 1;
        }
        else {
            right = mid - 1;
        }
    }

    return -1;
}

這個程式,相信只要是一個合格的程式設計師應該都會寫。 稍微注意一點, 每次移動left和right指標的時候,需要在mid的基礎上+1或者-1, 防止出現死迴圈, 程式也就能夠正確的執行。

但如果條件稍微變化一下, 你還會寫嗎?如,陣列之中的資料可能可以重複,要求返回匹配的資料的最小(或最大)的下標;更近一步, 需要找出陣列中第一個大於key的元素(也就是最小的大於key的元素的)下標,等等。 這些,雖然只有一點點的變化,實現的時候確實要更加的細心。 下面列出了這些二分檢索變種的實現。

1、找出第一個與key相等的元素


// 查詢第一個相等的元素
static int findFirstEqual(int[] array, int key) {
    int left = 0;
    int right = array.length - 1;

    // 這裡必須是 <=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (array[mid] >= key) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    if (left < array.length && array[left] == key) {
        return left;
    }
    
    return -1;
}

2、找出最後一個與key相等的元素

// 查詢最後一個相等的元素
static int findLastEqual(int[] array, int key) {
    int left = 0;
    int right = array.length - 1;

    // 這裡必須是 <=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (array[mid] <= key) {
            left = mid + 1;
        }
        else {
            right = mid - 1;
        }
    }
    if (right >= 0 && array[right] == key) {
        return right;
    }

    return -1;
}

3、查詢第一個等於或者大於Key的元素

// 查詢第一個等於或者大於key的元素
static int findFirstEqualLarger(int[] array, int key) {
    int left = 0;
    int right = array.length - 1;

    // 這裡必須是 <=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (array[mid] >= key) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return left;
}

4、查詢第一個大於key的元素

// 查詢第一個大於key的元素
static int findFirstLarger(int[] array, int key) {
    int left = 0;
    int right = array.length - 1;

    // 這裡必須是 <=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (array[mid] > key) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return left;
}

5、查詢最後一個等於或者小於key的元素

// 查詢最後一個等於或者小於key的元素
static int findLastEqualSmaller(int[] array, int key) {
    int left = 0;
    int right = array.length - 1;

    // 這裡必須是 <=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (array[mid] > key) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return right;
}

6、查詢最後一個小於key的元素

// 查詢最後一個小於key的元素
static int findLastSmaller(int[] array, int key) {
    int left = 0;
    int right = array.length - 1;

    // 這裡必須是 <=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (array[mid] >= key) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return right;
}

接下來,大家可以對這四種變種演算法進行相應的測試。

很多的時候,應用二分檢索的地方都不是直接的查詢和key相等的元素,而是使用上面提到的二分檢索的各個變種,熟練掌握了這些變種,當你再次使用二分檢索的檢索的時候就會感覺的更加的得心應手了。

讀者福利

針對於上面的文章我總結出了網際網路公司java程式設計師面試涉及到的絕大部分面試題及答案做成了文件和架構視訊資料免費分享給大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分散式、高併發等架構技術資料),希望能幫助到您面試前的複習且找到一個好的工作,也節省大家在網上搜索資料的時間來學習。

資料獲取方式:加qun群:956011797點選立即加入 找管理小姐姐免費獲取!

合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!

相關推薦

一道簡單試題竟然90程式設計師不能這個演算法完全正確

前段時間,在論壇上看到有統計說有90%的程式設計師不能夠寫對簡單的二分法。二分法不是很簡單的嗎? 這難道不是聳人聽聞? 其實,

一道Python試題給出d = [True, False, True, False, True],請利用列表d,只用一句話返回列表[0,2,4]

分享 忽略 class pytho 面試題 inf pos 如何 返回   前言:還是我,一個不知死活的小白,冒著生命危險去了一家有逼格的公司面試,去面試的路上就經歷了一番波折,公交車死等不來,最後差點誤了面試時間,這都不算什麽了,雖然對面試不抱什麽希望,但在技術面被虐成了

史上最難的一道Java試題分析篇

start 共享數據 jdk 不存在 記得 .sh 線程優先級 oss 滿足 無意中了解到如下題目,覺得蠻好。 題目如下: 該程序的輸出結果? 程序輸出結果 考察知識點 synchronize實例鎖。 並發下的內存可見性。 在java中,多線程的程序最難理解、調試,很多時候

以後綴名為分類檔案分別儲存到數組裡(朋友的一道簡單試題

<?php $dir = scandir('C:\Users\Administrator\Desktop\images'); echo '<pre>'; // print_r($dir); $gif = array(); $png = array(); $jpg = array()

Hive試題hive哪些udf函式,作用

UDF(user-defined function)作用於單個數據行,產生一個數據行作為輸出。(數學函式,字串函式) UDAF(使用者定義聚集函式 User- Defined Aggregation Funcation):接收多個輸入資料行,併產生一個輸出資料行。(count,max)

一道簡單試題來解讀JS中的閉包和作用域

先上程式碼 var count=10;//全域性作用域 標記為f1 function add(){ var count=0;//函式全域性作用域 標記為f2 return function(){ count+=1;//函式的內部作用域 alert(

試題C++了malloc/free,為什麼還需要new、delete?

1、面試寶典面試題(P81):C++有了malloc/free,為什麼還需要new、delete? malloc與free是C、C++語言的標準庫函式,new/delete是C++的運算子。他們都用於申請動態記憶體和釋放記憶體。 對於非內部資料型別的物件而言,只用mall

經典的一道JAVA試題A、B執行緒迴圈列印A、B

1、問題描述 通過Java多執行緒方式實現迴圈順序列印A、B,而且保證無論多少次迴圈,都不亂序? 2、問題的解決方案 其實這個問題,背後考察的是一個生產者和消費者的問題。即:要保證當前一個執行緒的任務完成之後,再去執行另一個執行緒的任務。由多種解決方法: 1、利用w

試題JQuery幾種選擇器?

很多種,大概歸納為9種。 (1)基本 #id element .class * selector1,selector2,selectorN (2)層次選擇器: ancestor descendant parent > child prev + next

試題陣列沒有length()方法? 字串沒有length()方法? 集合沒有length()方法?

陣列求長度用length屬性 字串求長度用length()方法 集合求長度用size()方法 程式舉例: package 集合.length_size; import java.util.ArrayList; import java.util.List; public

一道Hive試題累積報表

我們有如下的使用者訪問資料: userId visitDate visitCount u01 2017-01-21 5 u02 2017-01-23 6 u03 2017-01-22 8

價值的50道java試題 適用於准入職Java程式設計師

下面的內容是對網上原有的Java面試題集及答案進行了全面修訂之後給出的負責任的題目和答案,原來的題目中有很多重複題目和無價值的題目,還有不少的參考答案也是錯誤的,修改後的Java面試題集參照了JDK最新版本,去掉了EJB 2.x等無用內容,補充了資料結構和演算法相關的題目

C/C++試題編寫類String的建構函式、解構函式和賦值函式

考點:建構函式、解構函式和賦值函式的編寫方法出現頻率:☆☆☆☆☆已知類String的原型為:        class String        {        public:                String(const char *str = NULL);

一線網際網路常見的14個Java試題,你顫抖了嗎程式設計師

跳槽不算頻繁,但參加過不少面試(電話面試、face to face面試),面過大/小公司、網際網路/傳統軟體公司,麵糊過(眼高手低,缺乏實戰經驗,掛掉),也面過人,所幸未因失敗而氣餒,在此過程中不斷查缺補漏,養成了踏實、追本溯源、持續改進的習慣,特此將自己經歷過、構思過的一些面試題記錄下來,如果答案有問題

最近整理的一些常見的試題,面試大全,黑馬程式設計師面試寶典題庫---最新技術--篇

第八章 最新技術(評論區留言獲取原件) 一、 Redis 1. Redis 的特點?        Redis 是由義大利人 Salvatore Sanfilippo(網名: antirez)開發的一款記憶體快取記憶體資料庫。 Redis

最近整理的一些常見的試題,面試大全,黑馬程式設計師面試寶典題庫---框架--篇

框架(評論留言獲取原件) 一、 SpringMVC 1. SpringMVC 的工作原理 a. 使用者向伺服器傳送請求,請求被 springMVC 前端控制器 DispatchServlet 捕獲; b. DispatcherServle 對請求 URL 進行解析,得到請求資源

最近整理的一些常見的試題,面試大全,黑馬程式設計師面試寶典題庫---資料庫--篇

一、 Mysql 1. SQL 的 select 語句完整的執行順序 SQL Select 語句完整的執行順序: 1、 from 子句組裝來自不同資料來源的資料; 2、 where 子句基於指定的條件對記錄行進行篩選; 3、 group by 子句將資料劃分為多個分組; 4、使用聚集

最近整理的一些常見的試題,面試大全,黑馬程式設計師面試寶典題庫---JavaWEE高階篇

一、 Filter 和 Listener(評論留言獲取原件) 可參見:https://www.cnblogs.com/libingbin/p/5985647.html 二、 AJAX 1. 談談你對 ajax 的認識? Ajax 是一種建立互動式網頁應用的的網頁開發技術;

最近整理的一些常見的試題,面試大全,黑馬程式設計師面試寶典題庫---JavaWEB基礎篇

一、 JDBC 技術(評論留言獲取原件) 1. 說下原生 jdbc 操作資料庫流程?(2017-11-25-wzz) 第一步: Class.forName()載入資料庫連線驅動; 第二步: DriverManager.getConnection()獲取資料連線物件; 第三步:根據 SQL

試題一個射擊運動員打靶,靶一共有10環,連開10槍打中90環的可能性多少種?請用遞迴算

下面程式碼試用C#寫的 using System ; public class M { //public static int[] store; //相當於設定了全域性變數 //這個全域性變數sum是包含在M類中的 public static int sum; pub