此问题来自leetcode:
给出一个以num升序排列的整数数组,找到给定目标值的开始和结束位置。
您的算法的运行时复杂度必须为O(log n)的顺序。
如果在数组中找不到目标,则返回[-1,-1]。
示例1:
输入:nums = [5,7,7,8,8,10],目标= 8 输出:[3,4]
这是我的代码:
#include <vector>
#include <iostream>
using namespace std;
vector<int> searchRange(vector<int>& nums, int target)
{
int left = 0;
int right = (int)nums.size() - 1;
std::vector<int> result;
while(left <= right)
{
auto mid = (int)(left + right) / 2;
if(nums[mid] < target)
left = mid + 1;
else
right = mid;
}
int next_left = left;
int next_right = (int) nums.size() - 1;
while(next_left < next_right)
{
auto mid = (int)(left + right + 1) / 2;
if(nums[mid] > target)
next_right = mid - 1;
else
next_left = mid;
}
result = {next_left, next_right};
return result;
}
int main()
{
std::vector<int> nums = {1,2,2,2,2,4};
int target = 2;
auto result = searchRange(nums, target);
for(auto it: result)
std::cout << it << " ";
return 0;
}
我不断超过时间限制。我不知道如何解决它,任何帮助将不胜感激。
答案 0 :(得分:4)
在第二个循环中,此行
auto mid = (int)(left + right + 1) / 2;
应该是
auto mid = (int)(next_left + next_right + 1) / 2;
答案 1 :(得分:2)
有关跟踪逻辑错误的建议。
在while
循环中添加几行以查看索引如何变化。
while(left <= right)
{
auto mid = (int)(left + right) / 2;
if(nums[mid] < target)
left = mid + 1;
else
right = mid;
// Debugging output.
std::cout << "left: " << left
<< ", mid: " << mid
<< ", right: " << right << std::endl;
}
和
while(next_left < next_right)
{
// Incorrect.
// auto mid = (int)(left + right + 1) / 2;
auto mid = (int)(next_left + next_right + 1) / 2;
if(nums[mid] > target)
next_right = mid - 1;
else
next_left = mid;
// Debugging output.
std::cout << "next_left: " << next_left
<< ", mid: " << mid
<< ", next_right: " << next_right << std::endl;
}
那应该引导您朝正确的方向。
答案 2 :(得分:1)
要找到左索引
auto mid = (int)(left + right) / 2;
要找到正确的索引
auto mid = (int)(next_left + next_right + 1) / 2;
我认为您应该使用
result = {left, next_right};
返回正确的结果,它与{-1,-1}一起使用