• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 【劍指offer之二分查找】二分查找類型

    標簽: 劍指offer  算法  leetcode  數據結構  二分查找  


    概述

    本篇文章記錄劍指offer標簽為二分查找類的題。二分的模板太多了,本篇文章用的二分模板都是我之前發過的模板,附上鏈接:【算法模板】二分查找下面的題都是在力扣上面做的,可以按照題名搜索即可

    題不太多,建議刷刷leetcode上面二分的題,leetcode上面刷個10多道就夠了

    劍指 Offer 53 - II 0~n-1中缺失的數字

    image-20201114230704922

    二分

    由題意,我們可以將該數組分成兩部分

    image-20201105123409994

    第一部分是0 - x-1中, i = nums[i] , 第二部分是x - n - 1種中, i != nums[i]的則可以使用二分查找,我們要找到位置就是第一個i != nums[i]的位置。

    邊界情況是整個數組都是上圖中藍顏色的部分,我們要返回的值就是下一個數了

    時間復雜度O(logN),空間復雜度O(1)

    代碼:

    class Solution {
    public:
        int getMissingNumber(vector<int>& nums) {
            if (nums.empty()) return 0;
            int l = 0 , r = nums.size() - 1;
            //二分查找,找到第一個 i != nums[i]的位置
            while ( l < r){
                int mid = l + r >> 1;
                if (mid != nums[mid]) r = mid;
                else l = mid + 1;
            }
            //邊界情況,整個數組都是升序
            if (nums[l] == l) l ++;
            return l;
        }
    };
    

    劍指 Offer 53 - I 在排序數組中查找數字 I

    image-20201114232142733

    二分

    因為是排序好的數組,所以相同元素一定是連續存儲在數組中的。要統計出現次數,我們只需要找到該數字在數組中第一次出現的位置和最后一次出現的位置即可

    image-20201114233207506

    我們需要做兩次二分查找,找第一次個>=x的位置和第一個<=x的位置。這和二分模板是一模一樣,具體想看模板請翻閱到文章的頭部。

    時間復雜度O(logN),空間復雜度O(1)

    代碼:

    class Solution {
    public:
        int search(vector<int>& nums, int target) {
            //特判空數組
            if (nums.empty()) return 0;
            //第一次二分查找
            int start;
            int l = 0 , r = nums.size() - 1;
            while (l < r){
                int mid = l + r >> 1;
                if (nums[mid] >= target) r = mid ;
                else l = mid + 1;
            }
            //數組不存在target
            if (nums[l] != target) return 0;
            start = l;
            //第二次二分查找
            l = 0 , r = nums.size() - 1;
            while (l < r){
                int mid = l + r + 1 >> 1;
                if (nums[mid] <= target) l = mid;
                else r = mid - 1;
            }
            return l - start + 1;
        }
    };
    

    劍指 Offer 11 旋轉數組的最小數字

    image-20201114233323101

    二分

    image-20201114233727418

    如圖,本來是遞增的序列經過旋轉后會變成這樣,前面一段是遞增的,后面一段也是遞增的。者兩段是被第一個元素分割的

    我們可以用二分找到第一段的最后一個位置,然后判斷第二段是否存在

    • 如果第二段存在,則第二段的第一個位置即最小元素
    • 如果第二段不存在,則第一段的第一個元素為最小元素

    該題由于有重復元素,我們所以可能存在第一段的開頭和第二段的結尾可能都是相等的,我們需要用第一個元素作為兩段的分割,因為存在相等元素,不能保證我們能夠分清兩端,所以需要將第二段末尾和第一段的第一個元素相同的刪去。這樣能夠保證我們能夠分割兩段。

    時間復雜度O(logN),O(1)

    代碼:

    class Solution {
    public:
        int minArray(vector<int>& nums) {
            //去除第二段和第一段第一個元素相同的元素
            int k = nums.size() - 1;
            while (k >= 0 && nums[k] == nums[0]) k --;
            //數組全是相同的
            if (k < 0) return nums[0];
            //二分,找到第一段最后一個元素
            int l = 0 , r = k ;
            while (l < r){
                int mid = l + r + 1 >> 1;
                if (nums[mid] >= nums[0]) l = mid;
                else r = mid - 1;
            }
            //判斷第二段是否存在
            if (r == k) return nums[0];
            return nums[r + 1];
        }
    };
    

    r = mid - 1;
    }
    //判斷第二段是否存在
    if (r == k) return nums[0];
    return nums[r + 1];
    }
    };

    
    
    版權聲明:本文為Miiiiiiiiiii原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/Miiiiiiiiiii/article/details/109698732

    智能推薦

    PAT (Basic Level) Practise (中文) 1079. 延遲的回文數 (20)

    給定一個 k+1 位的正整數 N,寫成 ak...a1a0 的形式,其中對所有 i 有 0 <= ai < 10 且 ak > 0。N 被稱為一個回文數,當且僅當對所有 i 有 ai = ak-i。零也被定義為一個回文數。 非回文數也可以通過一系列操作變出回文數。首先將該數字逆轉,再將逆轉數與該數相加,如果和還不是一個回文數,就重復這個逆轉再相加的操作,直到一個回文數出現。如果一...

    insufficient free space available after evicting expired cache entries-consider increasing the maxim

    背景 項目中需要上傳學生證照片至服務器中,過了一段時間查看日志才發現,出現了一些小小的問題,主要是緩存不足造成的問題。 事故現場 console警告緩存不夠。 根據apache官方文檔: http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html The maximum size of the static resource cach...

    Yarn的調度器(三)

    文章目錄 1. Yarn調度流程 1.1 Yarn分層調度 1.2 Yarn調度觸發過程 2. Yarn調度器分析 2.1 FIFO調度器 2.2 Capacity調度器 2.3 Fair調度器 1. Yarn調度流程 1.1 Yarn分層調度 在 YARN 中資源分配共分成兩個層級,第一層是全局應用的資源分配,第二個層 級在 ApplicationMaster 層面,ApplicationMas...

    東華oj-進階題第87題-擠牛奶

    87 擠牛奶 作者: xxx時間限制: 1S章節: 結構體 問題描述 : 三個農民每天清晨5點起床,然后去牛棚給3頭牛擠奶。第一個農民在300時刻(從5點開始計時,秒為單位)給他的牛擠奶,一直到1000時刻。第二個農民在700時刻開始,在 1200時刻結束。第三個農民在1500時刻開始2100時刻結束。期間最長的至少有一個農民在擠奶的連續時間為900秒(從300時刻到1200時刻),而最長的無人擠...

    猜你喜歡

    雜文

    首頁 管理 隨筆- 42  文章- 0  評論- 0  基于LNMP平臺部署NextCloud私有云盤 一、NextCloud概述 云盤這個詞無論是做技術出身的朋友還是普通的網民,想必已經聽的非常多了,在日常生活當中我們用的最多的云盤莫過于百度網盤了 在前幾年百花齊放的網盤市場,到現如今只剩下了百度網盤,說起百度網盤大家并不陌生,特別是它限速的特征,讓廣大朋友久久不能...

    項目中實體類加lombok注解后,使用fastjson轉JSONObject字段名首字母變大寫

    先來回顧一下場景: 項目中定義一個實體類,用于和數據庫做對應,這里先貼上實體類的簡化定義(只保留一個字段): 說明: 這個實體類的定義就是常見操作,定義字段變量然后讓lombok幫我們生成get、set等方法。 然后呢,我們把數據庫中的查詢出來并映射到這個實體類之后,下一步操作就是返回到前端,代碼如下: Controller層代碼: Service層代碼: 至此都是并沒有什么“騷操作&...

    Spring注解驅動開發(六)

    [源碼]-Spring容器創建-BeanFactory預準備 [源碼]-Spring容器創建-執行BeanFactoryPostProcessor [源碼]-Spring容器創建-注冊BeanPostProcessors [源碼]-Spring容器創建-初始化MessageSource [源碼]-Spring容器創建-初始化事件派發器、監聽器等 [源碼]-Spring容器創建-Bean創建完成 [...

    自定義JsonUtil工具類,封裝了:string,list,Map等數據類型的互相轉換。

    自定義JsonUtil(Json轉換工具類) 前言 提供了 對string、list、list、Map 等類型數據之間的相互轉換方法。 高級封裝:對時間格式、NULL數據、NULL字段做了相關處理。 0、pom依賴 1、JsonUtil.java: TestPojo.java: 2、Main方法測試結果:...

    手寫tomcat系列2-第一個Servlet容器

    從大局開始先上UML圖: 1.HttpServer1:負責處理接受請求,依賴(dependency)Request類和Response類;關聯(association)ServletProcessor1和StaticResourceProcessor; 2.ServletProcessor1:處理servlet請求,依賴(dependency)Request類和Response類。有點小干貨,有興...

    精品国产乱码久久久久久蜜桃不卡