LeetCode 分類刷題:34. 在排序數組中查找元素的第一個和最后一個位置

題目

給你一個按照非遞減順序排列的整數數組?nums,和一個目標值?target。請你找出給定目標值在數組中的開始位置和結束位置。

如果數組中不存在目標值?target,返回?[-1, -1]

你必須設計并實現時間復雜度為?O(log n)?的算法解決此問題。

示例 1:

輸入:nums = [5,7,7,8,8,10], target = 8
輸出:[3,4]

示例?2:

輸入:nums = [5,7,7,8,8,10], target = 6
輸出:[-1,-1]

示例 3:

輸入:nums = [], target = 0
輸出:[-1,-1]

解析

問:如何理解 end = lowerBound(nums, target + 1) - 1 這段代碼?

答:要想找到 ≤target 的最后一個數,無需單獨再寫一個二分。我們可以先找到這個數的右邊相鄰數字,也就是 >target 的第一個數。在所有數都是整數的前提下,>target 等價于 ≥target+1,這樣就可以復用我們已經寫好的二分函數了,即 lowerBound(nums, target + 1),算出這個數的下標后,將其減一,就得到 ≤target 的最后一個數的下標。

問:如果 ≥target+1 的第一個數不存在怎么辦?

答:這說明數組中的數都 ≤target。如果數組中有 target,那么數組的最后一個數(下標 n?1)就是 target(因為數組是遞增的)。同時,lowerBound(nums, target + 1) 在這種情況下會返回 n,減一得到 n?1,這正是我們要計算的下標。

問:為什么要寫 left + (right - left) / 2?

答:在面試或者實際場景中,你不一定知道輸入的數組有多長,萬一數組長度達到 int 最大值,left + right 可能會發生加法溢出。當然,如果只看本題的數據范圍,寫 (left + right) / 2 也可以。對于 Python 來說,由于沒有溢出這個概念,所以可以直接相加。

問:怎么判斷我寫的是哪一種二分?

答:看 while 循環的條件,如果是 left <= right,就是閉區間;如果是 left < right,就是半閉半開區間;如果是 left + 1 < right,就是開區間。

問:對于閉區間寫法,為什么 nums[mid] >= target 的時候要寫 right = mid - 1?此時的 mid 不是有可能是答案嗎?這樣寫不會錯過答案嗎?

答:答案在區間外面,不在區間里面。如果覺得答案在區間里面的話,請思考這個問題:閉區間循環結束后 left>right,區間 [left,right] 是空的,什么也沒有,難道答案在空區間里面嗎?

問:我看到一種二分的寫法,在二分的過程中,額外記錄答案的值,你對此怎么看?

答:喜歡這種寫法的同學,推薦寫開區間二分,因為開區間二分 if 條件成立時更新的是哪個變量,最后返回的也就是哪個變量。這和記錄答案的做法如出一轍。

問:關于開區間二分,如何理解 ?1 和 n 這兩個下標?

答:可以假設 nums[?1]=?∞ 以及 nums[n]=∞,此時 nums 仍然是有序的。在這種情況下,nums[?1]<target,所以 ?1 是紅色;nums[n]≥target,所以 n 是藍色。

作者:靈茶山艾府
鏈接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/solutions/1980196/er-fen-cha-zhao-zong-shi-xie-bu-dui-yi-g-t9l9/
來源:力扣(LeetCode)

答案

class Solution:# lower_bound 返回最小的滿足 nums[i] >= target 的下標 i# 如果數組為空,或者所有數都 < target,則返回 len(nums)# 要求 nums 是非遞減的,即 nums[i] <= nums[i + 1]def lower_bound(self, nums: List[int], target: int) -> int:left, right = -1, len(nums)  # 開區間 (left, right)while left + 1 < right:  # 區間不為空mid = (left + right) // 2# 循環不變量:# nums[left] < target# nums[right] >= targetif nums[mid] >= target:right = mid  # 范圍縮小到 (left, mid)else:left = mid  # 范圍縮小到 (mid, right)# 循環結束后 left+1 = right# 此時 nums[left] < target 而 nums[right] >= target# 所以 right 就是第一個 >= target 的元素下標return rightdef searchRange(self, nums: List[int], target: int) -> List[int]:start = self.lower_bound(nums, target)  # 選擇其中一種寫法即可if start == len(nums) or nums[start] != target:return [-1, -1]  # nums 中沒有 target# 如果 start 存在,那么 end 必定存在end = self.lower_bound(nums, target + 1) - 1return [start, end]# 作者:靈茶山艾府
# 鏈接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/solutions/1980196/er-fen-cha-zhao-zong-shi-xie-bu-dui-yi-g-t9l9/
# 來源:力扣(LeetCode)

復雜度分析

時間復雜度:O(logn),其中?n?為?nums?的長度。

空間復雜度:O(1),僅用到若干額外變量。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/94520.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/94520.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/94520.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

自建知識庫,向量數據庫 (十二)之 文章向量搜索——仙盟創夢IDE

“未來之窗” 文章向量搜索&#xff1a;多領域應用與學習指南 在數字化浪潮中&#xff0c;“未來之窗” 文章向量搜索憑借其獨特的技術優勢&#xff0c;在酒店、電商、診療及知識庫等多個領域展現出巨大的應用潛力&#xff0c;為各行業的信息處理與檢索帶來了全新的視角和高效…

深度剖析:基于反射的.NET二進制序列化器設計與實現

&#x1f50d; 深度剖析&#xff1a;基于反射的.NET二進制序列化器設計與實現本文將從底層原理到高級優化&#xff0c;全面剖析一個基于反射的.NET二進制序列化器的設計與實現&#xff0c;涵蓋類型系統處理、內存布局、遞歸算法、性能優化等核心主題。1. 設計哲學與架構總覽 1.…

如何在 Ubuntu 上安裝和配置 Samba ?

Samba 是一個開源程序&#xff0c;用于文件共享和網絡打印&#xff0c;使用 SMB 協議。現在基本上用于提供在 Windows 上可訪問的 Linux 文件共享系統。 本文介紹如何在 Ubuntu 上安裝和配置 Samba 服務器&#xff0c;以便跨文件夾共享網絡上不同的計算機。 Update Your Syst…

MATLAB實現CNN-GRU-Attention時序和空間特征結合-融合注意力機制混合神經網絡模型的風速預測

該 MATLAB 代碼實現了一個基于 CNN-GRU-Attention 時序和空間特征結合-融合注意力機制混合神經網絡模型的風速預測。以下是對代碼的簡要分析&#xff1a;一、主要功能 該代碼用于風速時間序列預測&#xff0c;使用歷史風速特征數據&#xff08;18個特征&#xff0c;75天&#x…

【升級版】從零到一訓練一個 0.6B 的 MoE 大語言模型

前文&#xff1a;從零到一訓練一個 0.6B 的 MoE 大語言模型&#xff0c;本次升級完全重新從零開始重新訓練。主要升級如下&#xff1a; 替換預訓練數據集&#xff0c;使用序列猴子通用文本數據集進行預訓練。使用更先進的訓練方法。新增思考模式控制&#xff0c;可通過添加/th…

51單片機-實現定時器模塊教程

本章概述思維導圖&#xff1a; 51單片機驅動定時器模塊 CPU時序簡介 CPU時序定義了CPU內部操作的時間節奏&#xff0c;以下從四個時序周期進行逐步解析&#xff1b; 1、振蕩周期 振蕩周期&#xff1a;CPU內部時鐘源產生的最小時間單位&#xff0c;由晶振或內部振蕩器決定&am…

7.Kotlin的日期類

以下是 Kotlin 中常用時間類&#xff08;基于 java.time 包&#xff09;的核心方法及使用示例&#xff0c;參考數組方法的表格形式&#xff0c;按類分類展示&#xff1a; 一、LocalDate&#xff08;日期&#xff1a;年/月/日&#xff09;方法簽名返回值說明示例now(): LocalDat…

【Big Data】Hive技術解析:大數據倉庫的SQL橋梁

Hive作為Apache頂級項目&#xff0c;是Hadoop生態系統中最具影響力的SQL查詢引擎&#xff0c;它解決了大數據處理與傳統SQL技能之間的鴻溝。Hive的核心價值在于將類SQL查詢語言HiveQL無縫轉換為分布式計算框架MapReduce的任務&#xff0c;使數據分析師能夠利用熟悉的SQL語法操作…

Ubuntu2204server系統安裝postgresql14并配置密碼遠程連接

前言&#xff1a; 最近因項目需要安裝postgresql14&#xff0c;系統是ubuntu2204server系統&#xff0c;安裝好后發現無法實現遠程連接&#xff0c;解決了之后在此記錄一下解決方法。 疑問&#xff1a; 什么情況下需要配置postgresql遠程連接&#xff1f; ①如果是postgresql和…

【嵌入式】【搜集】狀態機、狀態遷移圖及狀態模式材料

文章目錄狀態機狀態機狀態機定義與核心特點狀態機總結狀態遷移圖狀態遷移圖狀態遷移圖核心概念與要素狀態遷移圖常見錯誤與規避狀態遷移圖總結狀態模式狀態模式狀態模式核心概念與組成狀態模式核心價值與適用場景狀態模式優缺點分析進階優化技巧行為模式總結狀態機 狀態機 狀…

Java學習歷程14——制作一款五子棋游戲(4)

上次我們基本實現了五子棋游戲的功能&#xff0c;這次我們進行一些優化和添加一些便于用戶使用的功能。新增功能及優化一、復盤功能復盤功能就是指在下完一局棋后&#xff0c;我們可以通過復盤按鈕使本局棋的所有棋子重頭開始自動下一遍。分析得知&#xff0c;我們首先要保存以…

記錄一次el-table+sortablejs的拖拽bug

bug回顧出現bug的情況時 當編輯表格過于緊湊的時候 有些非必要編輯或需要一眼看到的數據 移動到了el-table-column typeexpand時 同事&#xff1a;怎么拖拽功能用不了了 ok開始檢查代碼 當原來是個簡單的編輯表格 不涉及展開和簡單拖拽時 不會出現問題 解決了 出現了展開行以后…

利用go sort.Sort()排序自定義切片

1 sort.Sort()簡介2 核心功能3 調用前提4 代碼示例 1 sort.Sort()簡介 Go語言中的sort.Sort函數是標準庫提供的通用排序接口 2 核心功能 核心功能支持多種類型進行快速排序 基礎類型支持?&#xff1a;內置Ints、Float64s、Strings等函數直接排序常見切片 自定義排序?&a…

Elasticsearch腦裂緊急處理與預防

在 Elasticsearch 中出現 網絡分區&#xff08;Network Partition&#xff09; 或 腦裂&#xff08;Split-Brain&#xff09; 導致兩個子集群各自選出 Master 的情況&#xff0c;是非常嚴重的問題。比如這個場景&#xff08;20個節點分裂成兩個10節點的子集群&#xff0c;各自選…

華為網路設備學習-29(BGP協議 四)路由策略-實驗

示例 延伸-具體實驗1.代碼部分&#xff1a;基礎配置R1 [Huawei]int GigabitEthernet 0/0/0 [Huawei-GigabitEthernet0/0/0]ip address 10.1.13.1 24[Huawei]int LoopBack 1 [Huawei-LoopBack1]ip address 172.16.1.1 24 [Huawei-LoopBack1]q [Huawei]int LoopBack 2 [Huawei-Lo…

500系列狀態碼與可能的場景

501 Not Implemented&#xff08;未實現&#xff09;HTTP 方法不支持客戶端發送了 PUT、DELETE、PATCH 請求但服務器只實現了 GET 和 POST協議功能不支持客戶端使用了 HTTP/2 的某些高級特性服務器只支持 HTTP/1.1&#xff0c;無法處理&#xff0c;返回 501API 接口未完成開發中…

大數據、hadoop、爬蟲、spark項目開發設計之基于數據挖掘的交通流量分析研究

大數據、hadoop、爬蟲、spark項目開發設計之基于數據挖掘的交通流量分析研究

Pytest項目_day20(log日志)

Log日志優點&#xff1a;記錄程序運行信息&#xff0c;方便定位問題python日志模塊logging&#xff0c;日志等級如下&#xff1a; DEBUGINFO&#xff08;正常&#xff09;WARNINGERROR&#xff08;報錯&#xff09;示例代碼如下&#xff1a;import logging import os.path impo…

elasticsearch中的分詞器配置及使用

一、什么是分詞器&#xff1f; 在 Elasticsearch&#xff08;ES&#xff09;中&#xff0c;分詞器&#xff08;Analyzer&#xff09; 是處理文本的核心組件&#xff0c;負責將原始文本轉換為可搜索的索引詞&#xff08;Term&#xff09;。它是文本分析過程的核心&#xff0c;直…

《Linux 網絡編程二:UDP 與 TCP 的差異、應用及問題應對》

一、UDP 與 TCP 對比表對比項UDPTCP連接方式無需建立連接有連接&#xff08;三次握手建立&#xff0c;四次揮手斷開&#xff09;傳輸可靠性盡最大努力交付&#xff0c;可能丟包安全可靠的數據傳輸機制面向對象面向數據包面向數據流傳輸模式一對一、一對多傳輸本質一對一&#x…