当前位置:网站首页>Leetcode(34)——在排序数组中查找元素的第一个和最后一个位置
Leetcode(34)——在排序数组中查找元素的第一个和最后一个位置
2022-07-01 22:50:00 【SmileGuy17】
Leetcode(34)——在排序数组中查找元素的第一个和最后一个位置
题目
给你一个按照非递减顺序排列的整数数组 n u m s nums nums,和一个目标值 t a r g e t target target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 t a r g e t target target,返回 [ − 1 , − 1 ] [-1, -1] [−1,−1]。
你必须设计并实现时间复杂度为 O ( log n ) O(\log n) O(logn) 的算法解决此问题。
示例 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]
提示:
- 0 0 0 <= nums.length <= 1 0 5 10^5 105
- − 1 0 9 -10^9 −109 <= nums[i] <= 1 0 9 10^9 109
- nums 是一个非递减数组
- − 1 0 9 -10^9 −109 <= target <= 1 0 9 10^9 109
题解
方法一:暴力破解
思路
直观的思路肯定是从前往后遍历一遍。用两个变量记录第一次和最后一次遇见 target \textit{target} target 的下标,但这个方法的时间复杂度为 O ( n ) O(n) O(n),没有利用到数组升序排列的条件。
代码实现
我自己的:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> ans(2, -1);
int l = 0, r = nums.size()-1;
while(l <= r){
if(nums[l] == target){
ans[0] = l;
break;
}
l++;
}
if(l > r) return ans;
while(l <= r){
if(nums[r] == target){
ans[1] = r;
break;
}
r--;
}
return ans;
}
};
复杂度分析
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums 的长度
空间复杂度: O ( 1 ) O(1) O(1)
方法二:二分查找
思路
由于数组已经排序,因此整个数组是单调递增的,我们可以利用二分法来加速查找的过程。
考虑 target \textit{target} target 开始和结束位置,其实我们要找的就是数组中「第一个等于 target \textit{target} target 的位置」(记为 leftIdx \textit{leftIdx} leftIdx)和「第一个大于 target \textit{target} target 的位置减一」(记为 rightIdx \textit{rightIdx} rightIdx)。
二分查找中,寻找 leftIdx \textit{leftIdx} leftIdx 即为在数组中寻找第一个大于等于 target \textit{target} target 的下标,寻找 rightIdx \textit{rightIdx} rightIdx 即为在数组中寻找第一个大于 target \textit{target} target 的下标,然后将下标减一。两者的判断条件不同,为了代码的复用,我们定义 binarySearch(nums, target, lower)
表示在 nums \textit{nums} nums 数组中二分查找 target \textit{target} target 的位置,如果 lower \textit{lower} lower 为 t r u e \rm true true,则查找第一个大于等于 target \textit{target} target 的下标,否则查找第一个大于 target \textit{target} target 的下标。
最后,因为 target \textit{target} target 可能不存在数组中,因此我们需要重新校验我们得到的两个下标 leftIdx \textit{leftIdx} leftIdx 和 rightIdx \textit{rightIdx} rightIdx,看是否符合条件,如果符合条件就返回 [ leftIdx , rightIdx ] [\textit{leftIdx},\textit{rightIdx}] [leftIdx,rightIdx],不符合就返回 [ − 1 , − 1 ] [-1,-1] [−1,−1]。
代码实现
Leetcode 官方题解:
class Solution {
public:
int binarySearch(vector<int>& nums, int target, bool lower) {
int left = 0, right = (int)nums.size() - 1, ans = (int)nums.size();
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] > target || (lower && nums[mid] >= target)) {
right = mid - 1;
ans = mid;
} else {
left = mid + 1;
}
}
return ans;
}
vector<int> searchRange(vector<int>& nums, int target) {
int leftIdx = binarySearch(nums, target, true);
int rightIdx = binarySearch(nums, target, false) - 1;
if (leftIdx <= rightIdx && rightIdx < nums.size() && nums[leftIdx] == target && nums[rightIdx] == target) {
return vector<int>{
leftIdx, rightIdx};
}
return vector<int>{
-1, -1};
}
};
复杂度分析
时间复杂度: O ( log n ) O(\log n) O(logn),其中 n n n 为数组的长度。二分查找的时间复杂度为 O ( log n ) O(\log n) O(logn),一共会执行两次,因此总时间复杂度为 O ( log n ) O(\log n) O(logn)
空间复杂度: O ( 1 ) O(1) O(1)
边栏推荐
- Tcpdump command usage details
- 【Kotlin 第三方 】coil koltin协程图片加载库Coil类似Glide的图片加载第三方
- [MySQL] index creation, viewing and deletion
- Programming English vocabulary notebook
- AirServer最新Win64位个人版投屏软件
- plain framework的实际应用和扩展
- What is the mosaic tailgate?
- SWT/ANR问题--SWT 导致 low memory killer(LMK)
- Happy number [fast and slow pointer of ring PROBLEMS]
- Explain the volatile keyword
猜你喜欢
CADD课程学习(3)-- 靶点药物相互作用
思科考试--冗余网络
Explain JMM in detail
赵福全:短期解决保供,长期要打造安全、高效有韧性的供应链
window安装wsl(二)
众昂矿业:发展以氟化工为主的特色化工产业具有先天优势
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received
SWT/ANR问题--SWT 导致 kernel fuse deadlock
[MySQL] basic use of explain and the function of each column
Redis~02 cache: how to ensure data consistency in MySQL and redis when updating data?
随机推荐
Istio, ebpf and rsocket Broker: in depth study of service grid
Treatment of insufficient space in the root partition of armbain system
Some abilities can't be learned from work. Look at this article, more than 90% of peers
每日三题 6.30
RPA: Bank digitalization, business process automation "a small step", and loan review efficiency "a big step"
Armbain系统根分区空间不足处理
Tcpdump command usage details
想请教一下,证券开户选择哪个证券比较好?手机开户是安全么?
会声会影2022智能、快速、简单的视频剪辑软件
CKS CKA CKAD 将终端更改为远程桌面
通过Go语言创建CA与签发证书
flutter Unable to load asset: assets/images/888.png
证券开户选哪个证券公司比较好,哪个更安全
2022 R1 fast opening pressure vessel operation test questions and answers
Explain ThreadLocal in detail
2022年起重机司机(限桥式起重机)考试试题及模拟考试
2022安全员-C证考试题模拟考试题库及模拟考试
CADD课程学习(3)-- 靶点药物相互作用
【Swoole系列1】在Swoole的世界中,你将学习到什么?
Istio、eBPF 和 RSocket Broker:深入研究服务网格