本问题对应的 leetcode 原文链接:剑指 Offer 53 – I. 在排序数组中查找

问题描述

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

示例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

解题思路

视频讲解直达: 本题视频讲解

代码实现

class Solution {
    public int search(int[] nums, int target) {
        //常见题型:
        // 1.寻找第一个大于等于 target 的数   2.寻找第一个等于 target 的数
        // 3.寻找最后一个大于等于 target 的数 4.寻找最后一个等于 target 的数
        //PS:其实这里是不需要写两个查找函数的,可以把代码优化放在同一个方法里滴
        int left = search2(nums, target);
        int right = search4(nums, target);

        if(left < 0 || right < 0) return 0;
        return right - left + 1;



    }
    //2.寻找第一个等于 target 的数的下标
    int search2(int[] nums, int target){
        if(nums == null || nums.length <= 0){
            return -1;
        }
        int left = 0, right = nums.length - 1;
        while(left < right){
            // 向下取整
            int mid = (right - left) / 2 + left;
            if(nums[mid] >= target){
                right = mid;
            }else{
                left = mid + 1;
            }
        }
        // 判断该数是否存在
        if(nums[left] != target) return -1;
        return left;
    }

    //4.寻找最后一个等于 target 的数下标
    int search4(int[] nums, int target){
        if(nums == null || nums.length <= 0){
            return -1;
        }
        int left = 0, right = nums.length - 1;
        while(left < right){
            //向上取整
            int mid = (right - left + 1) / 2 + left;
            if(nums[mid] <= target){
                left = mid;
            }else{
                right = mid - 1;
            }
        }
        // 判断该数是否存在
        if(nums[left] != target) return -1;
        return left;
    }

}

时间复杂度:log(n)
额外空间复杂度:O(1)

Python

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        # 寻找第一个大于等于 target 的数的下标
        def search1(nums, target):
            if not nums:
                return -1

            left, right = 0, len(nums) - 1

            while left < right:
                mid = (right - left) // 2 + left

                if nums[mid] < target:
                    left = mid + 1
                else:
                    right = mid

            return left

        # 寻找最后一个大于等于 target 的数的下标
        def search2(nums, target):
            if not nums:
                return -1

            left, right = 0, len(nums) - 1

            while left < right:
                mid = (right - left + 1) // 2 + left

                if nums[mid] > target:
                    right = mid - 1
                else:
                    left = mid

            return left

        left = search1(nums, target)
        right = search2(nums, target)

        if left == -1 or right == -1 or nums[left] != target or nums[right] != target:
            return 0

        return right - left + 1

C++

class Solution {
public:
    int search(vector<int>& nums, int target) {
        // 寻找第一个大于等于 target 的数的下标
        auto search1 = [&](vector<int>& nums, int target) -> int {
            if (nums.empty()) {
                return -1;
            }

            int left = 0, right = nums.size() - 1;

            while (left < right) {
                int mid = left + (right - left) / 2;

                if (nums[mid] < target) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }

            return left;
        };

        // 寻找最后一个大于等于 target 的数的下标
        auto search2 = [&](vector<int>& nums, int target) -> int {
            if (nums.empty()) {
                return -1;
            }

            int left = 0, right = nums.size() - 1;

            while (left < right) {
                int mid = left + (right - left + 1) / 2;

                if (nums[mid] > target) {
                    right = mid - 1;
                } else {
                    left = mid;
                }
            }

            return left;
        };

        int left = search1(nums, target);
        int right = search2(nums, target);

        if (left == -1 || right == -1 || nums[left] != target || nums[right] != target) {
            return 0;
        }

        return right - left + 1;
    }
};

Go

func search(nums []int, target int) int {
    // 寻找第一个大于等于 target 的数的下标
    search1 := func(nums []int, target int) int {
        if len(nums) == 0 {
            return -1
        }

        left, right := 0, len(nums) - 1

        for left < right {
            mid := left + (right - left) / 2

            if nums[mid] < target {
                left = mid + 1
            } else {
                right = mid
            }
        }

        return left
    }

    // 寻找最后一个大于等于 target 的数的下标
    search2 := func(nums []int, target int) int {
        if len(nums) == 0 {
            return -1
        }

        left, right := 0, len(nums) - 1

        for left < right {
            mid := left + (right - left + 1) / 2

            if nums[mid] > target {
                right = mid - 1
            } else {
                left = mid
            }
        }

        return left
    }

    left := search1(nums, target)
    right := search2(nums, target)

    if left == -1 || right == -1 || nums[left] != target || nums[right] != target {
        return 0
    }

    return right - left + 1
}

JS

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function(nums, target) {
    //常见题型:
    // 1.寻找第一个大于等于 target 的数   2.寻找第一个等于 target 的数
    // 3.寻找最后一个大于等于 target 的数 4.寻找最后一个等于 target 的数
    //PS:其实这里是不需要写两个查找函数的,可以把代码优化放在同一个方法里滴
    let left = search2(nums, target);
    let right = search4(nums, target);

    if (left < 0 || right < 0) return 0;
    return right - left + 1;
};

//2.寻找第一个等于 target 的数的下标
function search2(nums, target) {
    if (nums == null || nums.length <= 0) {
        return -1;
    }
    let left = 0,
        right = nums.length - 1;
    while (left < right) {
        // 向下取整
        let mid = Math.floor((right - left) / 2 + left);
        if (nums[mid] >= target) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    // 判断该数是否存在
    if (nums[left] != target) return -1;
    return left;
}

//4.寻找最后一个等于 target 的数下标
function search4(nums, target) {
    if (nums == null || nums.length <= 0) {
        return -1;
    }
    let left = 0,
        right = nums.length - 1;
    while (left < right) {
        //向上取整
        let mid = Math.ceil((right - left + 1) / 2 + left);
        if (nums[mid] <= target) {
            left = mid;
        } else {
            right = mid - 1;
        }
    }
    // 判断该数是否存在
    if (nums[left] != target) return -1;
    return left;
}

发表回复

后才能评论