zoukankan      html  css  js  c++  java
  • 在排序数组中查找数字(Python and C++解法)

    题目:

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

    示例 1:

    输入: nums = [5,7,7,8,8,10], target = 8
    输出: 2
    示例 2:

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

    限制:

    0 <= 数组长度 <= 50000

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof

    思路:

      对于排序数组,自然需要想到使用二分查找法,找到目标数字后向两边遍历,找到第一个和最后一个目标数字,但是如果数组中都是目标数字的话,那么遍历就是O(n)的时间复杂度,这种方法和直接从头遍历一样。

      因此,可以考虑对于找第一个目标数字和找最后一个目标数字都使用二分查找法,那么时间复杂度为2*O(log n),但是需要使用变形的二分查找法,且该算法的实现需要注意细节。

      为了练习递归思想,解法使用递归而非循环实现。

    Python解法:

     1 class Solution:
     2     def search(self, nums: List[int], target: int) -> int:
     3         def getFirstTarget(nums, target, left, right):  # 找第一个目标数字
     4             if left > right:  # 递归终止条件
     5                 return -1  # 不能返回0,因为当数组的唯一元素就是目标元素,函数返回下标0
     6             midIndex = left + ((right - left) >> 1)
     7             midData = nums[midIndex]
     8             if midData < target:
     9                 left = midIndex + 1
    10             elif midData > target:
    11                 right = midIndex - 1
    12             else:  # 如果不判断midIndex-1>0,就需要midIndex == 0放在or左边
    13                 if midIndex == 0 or nums[midIndex-1] != target:
    14                     return midIndex
    15                 else:
    16                     right = midIndex - 1
    17             return getFirstTarget(nums, target, left, right)
    18         def getLastTarget(nums, target, left, right):
    19             if left > right:
    20                 return -1
    21             midIndex = left + ((right - left) >> 1)
    22             midData = nums[midIndex]
    23             if midData < target:
    24                 left = midIndex + 1
    25             elif midData > target:
    26                 right = midIndex - 1
    27             else:  
    28                 if midIndex == len(nums)-1 or nums[midIndex+1] != target:  # 如果不判断midIndex+1<len(nums)-1,就需要midIndex == len(nums)-1放在or左边
    29                     return midIndex
    30                 else:
    31                     left = midIndex + 1
    32             return getLastTarget(nums, target, left, right)
    33         
    34         count = 0
    35         if len(nums) > 0:
    36             firstIndex = getFirstTarget(nums, target, 0, len(nums)-1)
    37             lastIndex = getLastTarget(nums, target, 0, len(nums)-1)
    38             if firstIndex > -1 and lastIndex > -1:
    39                 count = lastIndex - firstIndex + 1
    40         return count

    C++解法:

    class Solution {
    public:
        int search(vector<int>& nums, int target) {
            int count = 0;
            if(nums.size() > 0) {
                int leftIndex = getFirstTarget(nums, target, 0, nums.size()-1);
                int rightIndex = getLastTarget(nums, target, 0, nums.size()-1);
                if(leftIndex > -1 && rightIndex > -1)
                    count = rightIndex - leftIndex + 1;
            }
            return count;
        }
    
        int getFirstTarget(vector<int>& theNums, int theTarget, int left, int right) {
            if(left > right)  // 递归终止条件
                return -1;
            int midIndex = (left + ((right - left) >> 1));
            int mindData = theNums[midIndex];
            if (mindData > theTarget)
                right = midIndex - 1;
            else if(mindData < theTarget)
                left = midIndex + 1;
            else {
                if(midIndex == 0 || theNums[midIndex-1] != theTarget)
                    return midIndex;
                else
                    right = midIndex - 1;
            }
            return getFirstTarget(theNums, theTarget, left, right);
        }
        int getLastTarget(vector<int>& theNums, int theTarget, int left, int right) {
            if(left > right)  // 递归终止条件
                return -1;
            int midIndex = (left + ((right - left) >> 1));
            int mindData = theNums[midIndex];
            if (mindData > theTarget)
                right = midIndex - 1;
            else if(mindData < theTarget)
                left = midIndex + 1;
            else {
                if(midIndex == theNums.size()-1 || theNums[midIndex+1] != theTarget)
                    return midIndex;
                else
                    left = midIndex + 1;
            }
            return getLastTarget(theNums, theTarget, left, right);
        }
    };
  • 相关阅读:
    Java构造和解析Json数据的两种方法详解一
    微信小程序-自定义组件
    微信小程序
    微信公众号
    微信小程序
    微信小程序
    微信小程序
    vue
    vue
    sass 和 css 互转网址
  • 原文地址:https://www.cnblogs.com/kongzimengzixiaozhuzi/p/13408570.html
Copyright © 2011-2022 走看看