面试官:聊一下二分法
來源:cnblogs.com/luoxn28/p/5767571.html
1、二分查找
二分查找是一個基礎的算法,也是面試中??嫉囊粋€知識點。二分查找就是將查找的鍵和子數組的中間鍵作比較,如果被查找的鍵小于中間鍵,就在左子數組繼續查找;如果大于中間鍵,就在右子數組中查找,否則中間鍵就是要找的元素。
/***?二分查找,找到該值在數組中的下標,否則為-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, 防止出現死循環, 程序也就能夠正確的運行。
注意:代碼中的判斷條件必須是while (left <= right),否則的話判斷條件不完整,比如:array[3] = {1, 3, 5};待查找的鍵為5,此時在(low < high)條件下就會找不到,因為low和high相等時,指向元素5,但是此時條件不成立,沒有進入while()中。
2、二分查找的變種
關于二分查找,如果條件稍微變換一下,比如:數組之中的數據可能可以重復,要求返回匹配的數據的最小(或最大)的下標;更近一步, 需要找出數組中第一個大于key的元素(也就是最小的大于key的元素的)下標,等等。這些,雖然只有一點點的變化,實現的時候確實要更加的細心。
二分查找的變種和二分查找原理一樣,主要就是變換判斷條件(也就是邊界條件),如果想直接看如何記憶這些變種的竅門,請直接翻到本文最后。下面來看幾種二分查找變種的代碼:
2.1、查找第一個與key相等的元素
查找第一個相等的元素,也就是說等于查找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.2、查找最后一個與key相等的元素
查找最后一個相等的元素,也就是說等于查找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; }2.3、查找最后一個等于或者小于key的元素
查找最后一個等于或者小于key的元素,也就是說等于查找key值的元素有好多個,返回這些元素最右邊的元素下標;如果沒有等于key值的元素,則返回小于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; }2.4、查找最后一個小于key的元素
查找最后一個小于key的元素,也就是說返回小于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; }2.5、查找第一個等于或者大于key的元素
查找第一個等于或者大于key的元素,也就是說等于查找key值的元素有好多個,返回這些元素最左邊的元素下標;如果沒有等于key值的元素,則返回大于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; }2.6、查找第一個大于key的元素
查找第一個等于key的元素,也就是說返回大于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; }3、二分查找變種總結
//?這里必須是?<= while?(left?<=?right)?{int?mid?=?(left?+?right)?/?2;if?(array[mid]???key)?{//...?right?=?mid?-?1;}else?{//?...?left?=?mid?+?1;} } return?xxx;二分查找變種較多,不過它們的“套路”是一樣的,以上代碼就是其套路,如何快速寫出二分查找的代碼,只需按照以下步驟即可:
1、首先判斷出是返回left,還是返回right
因為我們知道最后跳出while (left <= right)循環條件是right < left,且right = left - 1。最后right和left一定是卡在"邊界值"的左右兩邊,如果是比較值為key,查找小于等于(或者是小于)key的元素,則邊界值就是等于key的所有元素的最左邊那個,其實應該返回left。
以數組{1, 2, 3, 3, 4, 5}為例,如果需要查找第一個等于或者小于3的元素下標,我們比較的key值是3,則最后left和right需要滿足以下條件:
我們比較的key值是3,所以此時我們需要返回left。
2、判斷出比較符號
int?mid?=?(left?+?right)?/?2; if?(array[mid]???key)?{//...?right?=?xxx; } else?{//?...?left?=?xxx; }也就是這里的if (array[mid] ? key)?中的判斷符號,結合步驟1和給出的條件,如果是查找小于等于key的元素,則知道應該使用判斷符號>=,因為是要返回left,所以如果array[mid]等于或者大于key,就應該使用>=,以下是完整代碼
//?查找小于等于key的元素 int?mid?=?(left?+?right)?/?2; if?(array[mid]?>=?key)?{right?=?mid?-?1; } else?{left?=?mid?+?1; }【End】
查看更多面試題內容,請訪問《Java最常見200+面試題全解析》,它包含的模塊有:
Java、JVM?最常見面試題解析
Spring、Spring?MVC、MyBatis、Hibernate?面試題解析
MySQL、Redis?面試題解析
RabbitMQ、Kafka、Zookeeper?面試解析
微服務?Spring?Boot、Spring?Cloud?面試解析
掃描下面二維碼付費閱讀
關注下方二維碼,訂閱更多精彩內容。
轉發朋友圈,是對我最大的支持。
總結
以上是生活随笔為你收集整理的面试官:聊一下二分法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nodejs+nginx获取真实ip
- 下一篇: 你真的理解零拷贝了吗?