欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Java中二分法的基本思路和實(shí)現(xiàn)

 更新時(shí)間:2022年08月25日 09:02:09   作者:Grey  
二分法是一個(gè)非常高效的算法,它常常用于計(jì)算機(jī)的查找過(guò)程中。本文將通過(guò)示例為大家詳細(xì)講講二分法的基本思路和實(shí)現(xiàn),感興趣的可以了解一下

在一個(gè)有序數(shù)組中,找某個(gè)數(shù)是否存在

思路:

  • 由于是有序數(shù)組,可以先得到中點(diǎn)位置,中點(diǎn)可以把數(shù)組分為左右半邊。
  • 如果中點(diǎn)位置的值等于目標(biāo)值,直接返回中點(diǎn)位置。
  • 如果中點(diǎn)位置的值小于目標(biāo)值,則去數(shù)組中點(diǎn)左側(cè)按同樣的方式尋找。
  • 如果中點(diǎn)位置的值大于目標(biāo)值,則取數(shù)組中點(diǎn)右側(cè)按同樣的方式尋找。
  • 如果最后沒(méi)有找到,則返回:-1。

代碼

class Solution {
    public int search(int[] arr, int t) {
        if (arr == null || arr.length < 1) {
            return -1;
        }
        int l = 0;
        int r = arr.length - 1;
        while (l <= r) {
            int m = l + ((r - l) >> 1);
            if (arr[m] == t) {
                return m;
            } else if (arr[m] > t) {
                r = m - 1;
            } else {
                l = m + 1;
            }
        }
        return -1;
    }
}

時(shí)間復(fù)雜度 O(logN)。

在一個(gè)有序數(shù)組中,找大于等于某個(gè)數(shù)最左側(cè)的位置

示例 1:

輸入: nums = [1,3,5,6], target = 5

輸出: 2

說(shuō)明:如果要在num這個(gè)數(shù)組中插入 5 這個(gè)元素,應(yīng)該是插入在元素 3 和 元素 5 之間的位置,即 2 號(hào)位置。

示例 2:

輸入: nums = [1,3,5,6], target = 2

輸出: 1

說(shuō)明:如果要在num這個(gè)數(shù)組中插入 2 這個(gè)元素,應(yīng)該是插入在元素 1 和 元素 3 之間的位置,即 1 號(hào)位置。

示例 3:

輸入: nums = [1,3,5,6], target = 7

輸出: 4

說(shuō)明:如果要在num這個(gè)數(shù)組中插入 7 這個(gè)元素,應(yīng)該是插入在數(shù)組末尾,即 4 號(hào)位置。

通過(guò)上述示例可以知道,這題本質(zhì)上就是求在一個(gè)有序數(shù)組中,找大于等于某個(gè)數(shù)最左側(cè)的位置,如果不存在,就返回?cái)?shù)組長(zhǎng)度(表示插入在最末尾位置)

我們只需要在上例基礎(chǔ)上進(jìn)行簡(jiǎn)單改動(dòng)即可,上例中,我們找到滿足條件的位置就直接return

if (arr[m] == t) {
    return m;
}

在本問(wèn)題中,因?yàn)橐业阶钭髠?cè)的位置,所以,在遇到相等的時(shí)候,只需要先把位置記錄下來(lái),不用直接返回,然后繼續(xù)去左側(cè)找是否還有滿足條件的更左邊的位置。

同時(shí),在遇到arr[m] > t條件下,也需要記錄下此時(shí)的m位置,因?yàn)檫@也可能是滿足條件的位置。

代碼:

class Solution {
    public static int searchInsert(int[] arr, int t) {
        int ans = arr.length;
        int l = 0;
        int r = arr.length - 1;
        while (l <= r) {
            int m = l + ((r - l)>>1);
            if (arr[m] >= t) {
                ans = m;
                r = m - 1;
            } else  {
                l = m + 1;
            } 
        }
        return ans;
    }
}

整個(gè)算法的時(shí)間復(fù)雜度是O(logN)

在排序數(shù)組中查找元素的第一個(gè)和最后一個(gè)位置

思路

本題也是用二分來(lái)解,當(dāng)通過(guò)二分找到某個(gè)元素的時(shí)候,不急著返回,而是繼續(xù)往左(右)找,看能否找到更左(右)位置匹配的值。

代碼如下:

class Solution {
    public static int[] searchRange(int[] arr, int t) {
        if (arr == null || arr.length < 1) {
            return new int[]{-1, -1};
        }
        return new int[]{left(arr,t),right(arr,t)};   
    }
    public static int left(int[] arr, int t) {
        if (arr == null || arr.length < 1) {
            return -1;
        }
        int ans = -1;
        int l = 0;
        int r = arr.length - 1;
        while (l <= r) {
            int m = l + ((r - l) >> 1);
            if (arr[m] == t) {
               ans = m;
               r = m - 1;
            } else if (arr[m] < t) {
                l = m +1;
            } else {
                // arr[m] > t
                r = m - 1;
            }
        }
        return ans;
    }
    public static int right(int[] arr, int t) {
        if (arr == null || arr.length < 1) {
            return -1;
        }
        int ans = -1;
        int l = 0;
        int r = arr.length - 1;
        while (l <= r) {
            int m = l + ((r - l) >> 1);
            if (arr[m] == t) {
               ans = m;
               l = m + 1;
            } else if (arr[m] < t) {
                l = m +1;
            } else {
                // arr[m] > t
                r = m - 1;
            }
        }
        return ans;
    }
}

時(shí)間復(fù)雜度 O(logN)。

局部最大值問(wèn)題

思路

假設(shè)數(shù)組長(zhǎng)度為N,首先判斷0號(hào)位置的數(shù)和N-1位置的數(shù)是不是峰值位置。

0號(hào)位置只需要和1號(hào)位置比較,如果0號(hào)位置大,0號(hào)位置就是峰值位置,可以直接返回。

N-1號(hào)位置只需要和N-2號(hào)位置比較,如果N-1號(hào)位置大,N-1號(hào)位置就是峰值位置,可以直接返回。

如果0號(hào)位置和N-1在上輪比較中均是最小值,那么數(shù)組的樣子必然是如下情況:

由上圖可知,[0..1]區(qū)間內(nèi)是增長(zhǎng)趨勢(shì), [N-2...N-1]區(qū)間內(nèi)是下降趨勢(shì)。

那么峰值位置必在[1...N-2]之間出現(xiàn)。

此時(shí)可以通過(guò)二分來(lái)找峰值位置,先來(lái)到中點(diǎn)位置,假設(shè)為mid,如果中點(diǎn)位置的值比左右兩邊的值都大:

arr[mid] > arr[mid+1] && arr[mid] > arr[mid-1]

mid位置即峰值位置,直接返回。

否則,有如下兩種情況:

情況一:mid 位置的值比 mid - 1 位置的值小

趨勢(shì)如下圖:

則在[1...(mid-1)]區(qū)間內(nèi)繼續(xù)二分。

情況二:mid 位置的值比 mid + 1 位置的值小

趨勢(shì)是:

則在[(mid+1)...(N-2)]區(qū)間內(nèi)繼續(xù)上述二分。

完整代碼

public class LeetCode_0162_FindPeakElement {
    public static int findPeakElement(int[] nums) {
        if (nums.length == 1) {
            return 0;
        }
        int l = 0;
        int r = nums.length - 1;
        if (nums[l] > nums[l + 1]) {
            return l;
        }
        if (nums[r] > nums[r - 1]) {
            return r;
        }
        l = l + 1;
        r = r - 1;
        while (l <= r) {
            int mid = l + ((r - l) >> 1);
            if (nums[mid] > nums[mid + 1] && nums[mid] > nums[mid - 1]) {
                return mid;
            }
            if (nums[mid] < nums[mid + 1]) {
                l = mid + 1;
            } else if (nums[mid] < nums[mid - 1]) {
                r = mid - 1;
            }
        }
        return -1;
    }
}

時(shí)間復(fù)雜度O(logN)。

到此這篇關(guān)于詳解Java中二分法的基本思路和實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java二分法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Cloud Feign組成配置過(guò)程解析

    Spring Cloud Feign組成配置過(guò)程解析

    這篇文章主要介紹了Spring Cloud Feign組成配置過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 詳解java平臺(tái)解析協(xié)議相關(guān)備忘

    詳解java平臺(tái)解析協(xié)議相關(guān)備忘

    這篇文章主要介紹了詳解java平臺(tái)解析協(xié)議相關(guān)備忘,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 詳解Java類加載器與雙親委派機(jī)制

    詳解Java類加載器與雙親委派機(jī)制

    這篇文章主要為大家介紹一下Java中的類加載器與雙親委派機(jī)制,文中通過(guò)示例為大家進(jìn)行了詳細(xì)的介紹,對(duì)我們學(xué)習(xí)Java有一定幫助,需要的可以參考一下
    2022-08-08
  • Java獲取接口所有實(shí)現(xiàn)類的方式詳解

    Java獲取接口所有實(shí)現(xiàn)類的方式詳解

    這篇文章主要介紹了Java獲取接口所有實(shí)現(xiàn)類的方式詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Windows下Java調(diào)用可執(zhí)行文件代碼實(shí)例

    Windows下Java調(diào)用可執(zhí)行文件代碼實(shí)例

    這篇文章主要介紹了Windows下Java調(diào)用可執(zhí)行文件代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • springboot中rabbitmq實(shí)現(xiàn)消息可靠性機(jī)制詳解

    springboot中rabbitmq實(shí)現(xiàn)消息可靠性機(jī)制詳解

    這篇文章主要介紹了springboot中rabbitmq實(shí)現(xiàn)消息可靠性機(jī)制詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-09-09
  • java圖片滑動(dòng)驗(yàn)證(登錄驗(yàn)證)原理與實(shí)現(xiàn)方法詳解

    java圖片滑動(dòng)驗(yàn)證(登錄驗(yàn)證)原理與實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了java圖片滑動(dòng)驗(yàn)證(登錄驗(yàn)證)原理與實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了java圖片滑動(dòng)登錄驗(yàn)證的相關(guān)原理、實(shí)現(xiàn)方法與操作技巧,需要的朋友可以參考下
    2019-09-09
  • java編程兩種樹形菜單結(jié)構(gòu)的轉(zhuǎn)換代碼

    java編程兩種樹形菜單結(jié)構(gòu)的轉(zhuǎn)換代碼

    這篇文章主要介紹了java編程兩種樹形菜單結(jié)構(gòu)的轉(zhuǎn)換代碼,首先介紹了兩種樹形菜單結(jié)構(gòu)的代碼,然后展示了轉(zhuǎn)換器實(shí)例代碼,最后分享了相關(guān)實(shí)例及結(jié)果演示,具有一定借鑒價(jià)值,需要的朋友可以了解下。
    2017-12-12
  • Spring boot跨域設(shè)置實(shí)例詳解

    Spring boot跨域設(shè)置實(shí)例詳解

    這篇文章主要介紹了Spring boot跨域設(shè)置實(shí)例詳解,簡(jiǎn)單介紹了跨域的定義,原因,使用場(chǎng)景及解決方案,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Java面試題沖刺第五天--基礎(chǔ)篇2

    Java面試題沖刺第五天--基礎(chǔ)篇2

    這篇文章主要為大家分享了最有價(jià)值的三道java面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-07-07

最新評(píng)論