无限循环在哪里发生?

时间:2019-07-12 20:11:43

标签: c++

此问题来自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;
}

我不断超过时间限制。我不知道如何解决它,任何帮助将不胜感激。

3 个答案:

答案 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}一起使用