日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

34. 在排序数组中查找元素的第一个和最后一个位置012(二分查找+思路+详解+两种方法)Come Baby!!!!!!!! !

發布時間:2023/12/4 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 34. 在排序数组中查找元素的第一个和最后一个位置012(二分查找+思路+详解+两种方法)Come Baby!!!!!!!! ! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:題目

給定一個按照升序排列的整數數組 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]

二:思路

思路:1.我們求取給定數組范圍內 目標值的左邊界和右邊界
2.拿下方的例子來解釋:
nums = [5,7,7,8,8,10], target = 8
3.左邊界指的就是數組當中的元素值都小于等于目標值的范圍:5,7,7,8
右邊界:指的是數組當中的元素值都大于等于目標值的范圍:8,10
4.當我們求出目標值的左右邊界,也就求出了題目說的開始和結束位置

三:上碼

方法一:二分法

class Solution { public:vector<int> searchRange(vector<int>& v, int target) {//方法二:二分法/*思路:1.我們求取給定數組范圍內 目標值的左邊界和右邊界2.拿下方的例子來解釋:nums = [5,7,7,8,8,10], target = 83.左邊界指的就是數組當中的元素值都小于等于目標值的范圍:5,7,7,8右邊界:指的是數組當中的元素值都大于等于目標值的范圍:8,104.當我們求出目標值的左右邊界,也就求出了題目說的開始和結束位置 */int l = left_border(v,target);int r = right_border(v,target);if(l == -3 || r == -3){//證明根本就無該目標值 比如[3,4,6] 找 7return {-1,-1};}if(v[l+1] == target && v[r-1] == target)//得保證查詢到的元素存在return {l+1,r-1};//其他情況return{-1,-1};}//求取左邊界(即數組當中均小于目標值的范圍)int left_border(vector<int>& v, int target){int l = 0;int r = v.size() - 1;int mid;int temp = -3;while(l <= r){mid = (l+r)/2;if(v[mid] >= target){//這是結束的條件,因為已經出現要大于等于目標值的元素了r = mid - 1;temp = r;}else{l = mid + 1;//不斷接近目標值,}}return temp;}//求取右邊界(即數組當中的元素均大于目標值的范圍)int right_border(vector<int>& v, int target){int l = 0;int r = v.size() - 1;int mid;int temp = -3;while(l <= r){mid = (l+r)/2;if(v[mid] > target){r = mid - 1;//不斷縮小范圍接近目標值,從數組的右邊來}else{l = mid + 1;//證明查找到了出現小于等于目標值的元素時,這時循環也就結束了,因為 l > rtemp = l;}} return temp;}};

方法二:調用庫函數lower_bound,upper_bound

注意調用庫函數的區別:

lower_bound(開始位置,結束位置,目標值) - 開始位置 : 這個返回的是元素第一次出現的位置(如果查詢不到目標值則返回第一個比起大的元素下標)
upper_bound(開始位置,結束位置,目標值) - 開始位置 :這個返回的是有元素第一次大于目標值的位置,所以在本題中 要減一

注意這是升序數組當中調用的函數

我自己在測試用例時,用了個非升序的例子,害。。。。。。結果。。省略一萬句。。。

class Solution { public:vector<int> searchRange(vector<int>& v, int target) {// /**// 注意前提條件是輸入的數值是升序的 // */ //方法一:利用庫函數// //查詢某個元素第一次出現的下標 int l = lower_bound(v.begin(),v.end(),target) - v.begin();if( l == v.size() || v[l] != target){ return {-1,-1};}//返回的是第一個大于待查數值的地址int r = upper_bound(v.begin(),v.end(),target) - v.begin(); return {l,r-1};}};

四:補充vector中lower_bound(),upper_bound()的用法測試用例

#include<bits/stdc++.h> using namespace std;int main(){vector<int>v;int N,a;cin >> N >> a ;for(int i = 0; i < N; i++){int temp;cin >> temp;v.push_back(temp); } /**注意前提條件是輸入的數值是升序的 */ //查詢某個元素第一次出現的下標(如果查詢不到目標值則返回第一個比起大的元素下標)int l = lower_bound(v.begin(),v.end(),a) - v.begin();//返回的是第一個大于待查數值的地址 int r = upper_bound(v.begin(),v.end(),a) - v.begin();cout << l << " " << r - 1;} //6 3 //1 2 3 4 4 5 //6 9 //5 7 7 8 8 10

拿走不用謝!!

最后在啰嗦啰嗦,最好不要用庫函數,這道題,其實就是考察二分法的運用,對于這個庫函數其實知道就行,可以將他用到你寫的其他碼上,本題不建議使用!!

好了 就這樣!!加油 BOY!!! and girl!!!!!!!!!

總結

以上是生活随笔為你收集整理的34. 在排序数组中查找元素的第一个和最后一个位置012(二分查找+思路+详解+两种方法)Come Baby!!!!!!!! !的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。