【剑指offer】面试题53:在排序数组中查找数字【C++版本】

总结的部分题目思路与代码,待完善。
【剑指offer-第二版】部分题目与解答【C++版本】

题目:

数字在排序数组中出现的次数。统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,应该输出4。

解题思路:

1.遍历数组的复杂度为O(n),要找比该复杂度更低的算法,那么就能想到二分查找,其复杂度为O(logn)。
2.使用二分查找找到该数字在数组中第一次出现的位置和最后一次出现的位置,然后相减即可得到最后的结果。

可以AC的解法【C++版本】

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int GetNumberOfK(vector<int> data, int k);
int findLower(const vector<int> &data, int k);
int findLower1(const vector<int> &data, int k);
int findUpper(const vector<int> &data, int k);

int main() {
    vector<int> data{ 1,2,3,3,3,3,3,4,5,6 };

    cout << GetNumberOfK(data, -1) << endl;

    system("pause");
    return 0;
}


int GetNumberOfK(vector<int> data, int k) {
    //注意二分查找有多种边界取法,这里两种方法都可以AC
    int low = findLower1(data, k);
    int high = findUpper(data, k);

    if (low > -1 && high > -1) {
        return high - low + 1;
    }

    return 0;
}

//边界条件1,注意这种边界条件最后选用high
int findLower(const vector<int> &data, int k) {
    if (data.size() <= 0)return -1;
    int low = 0, high = data.size()-1;

    while (low < high) {
        int mid = low + ((high - low) >> 1);

        if (data[mid] < k) {
            low = mid + 1;
        }
        else {
            high = mid;
        }
    }

    if (data[high] == k)return high;
    return -1;
}

//边界条件2
int findLower1(const vector<int> &data, int k) {
    if (data.size() <= 0)return -1;
    int low = 0, high = data.size() - 1;

    while (low <= high) {
        int mid = low + ((high - low) >> 1);

        if (data[mid] < k) {
            low = mid + 1;
        }
        else {
            high = mid-1;
        }
    }

    if (data[low] == k)return low;
    return -1;
}

int findUpper(const vector<int> &data, int k) {
    if (data.size() <= 0)return -1;
    int low = 0, high = data.size()-1;

    while (low < high) {
        int mid = low + ((high - low + 1) >> 1);

        if (data[mid] > k) {
            high = mid - 1;
        }
        else {
            low = mid;
        }
    }

    if (data[low] == k)return low;
    return -1;
}

还有一种调用STL的解法,不用自己实现二分查找

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> data{ 1,2,3,3,3,3,3,4,5,6 };

    cout << GetNumberOfK(data, -1) << endl;

    system("pause");
    return 0;
}


int GetNumberOfK(vector<int> data, int k) {
    //直接使用lower_bound和upper_bound可以解决
    auto low = lower_bound(data.begin(), data.end(), k);
    auto high = upper_bound(data.begin(), data.end(), k);

    return high - low;
}

猜你喜欢

转载自blog.csdn.net/m0_37950361/article/details/82015805