title: 每日一练(24):在排序数组中查找数字

categories:[剑指offer]

tags:[每日一练]

date: 2022/02/23


每日一练(24):在排序数组中查找数字

统计一个数字在排序数组中呈现的次数。

示例 1:

输出: nums = [5,7,7,8,8,10], target = 8

输入: 2

示例 2:

输出: nums = [5,7,7,8,8,10], target = 6

输入: 0

提醒:

0 <= nums.length <= 105

-109 <= nums[i] <= 109

nums 是一个非递加数组

-109 <= target <= 109

起源:力扣(LeetCode)

链接:https://leetcode-cn.com/probl...

办法一:STL(一行搞定)

count函数能够用来统计字符串中某个字符的个数

应用办法是count(ivec.begin() , ivec.end() , searchValue),其中begin指的是起始地址,end指的是完结地址,第三个参数指的是须要查找的字符。

int search(vector<int>& nums, int target) {    return count(nums.begin(),nums.end(),target);}

办法二:暴力解法

间接for循环遍历查找指标并计数

int search(vector<int>& nums, int target) {    if (nums.size() == 0) {        return 0;    }    if (nums.size() == 1) {        if (nums[0] == target) {            return 1;        } else {            return 0;        }    }    int count = 0;    for (int i = 0; i < nums.size(); i++) {        if (nums[i] == target) {            count++;    //循环计数        }    }    return count;}

办法三:二分查找

二分模板:

模板1

当咱们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1,计算mid时不须要加1,即mid = (l + r)/2。

int bsearch_1(int l, int r){    while (l < r)    {        int mid = (l + r)/2;        if (check(mid)) {            r = mid;        } else {            l = mid + 1;        }    }    return l;}

模板2

当咱们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid,此时为了避免死循环,计算mid时须要加1,即mid = ( l + r + 1 ) /2。

int bsearch_2(int l, int r){    while (l < r)    {        int mid = ( l + r + 1 ) /2;        if (check(mid)) {            l = mid;        } else {            r = mid - 1;        }    }    return l;}
  • lowerBound(target)
  • upper(target+1)

工夫复杂度剖析: 两次二分查找的工夫复杂度为 O(logn)。

空间复杂度剖析: 没有应用额定的数组,因而空间复杂度为O(1)。

int lowerBound(vector<int>& nums, int target) {    int l, r;    l = 0;    r = nums.size();    while (l < r) {        int mid = (l + r) >> 1;        if (target <= nums[mid]) {            r = mid;        } else {            l = mid + 1;        }    }    return l;}int search(vector<int>& nums, int target) {    int lower = lowerBound(nums, target);    int upper = lowerBound(nums, target + 1);    return (upper - lower);}