zoukankan      html  css  js  c++  java
  • 二分查找——边界问题(leetcode 34,Offer 53

    """
    寻找决策边界分为寻找左侧边界、右侧边界
    寻找左侧边界,压缩右边界(当mid=target缩小right)
    寻找右侧边界,压缩左边界(当mid=target缩小left)
    """

    #寻找左侧边界
    def query_left_target_boundary_v1(list_num, target):
    left = 0
    right = len(list_num) - 1
    while left <= right:
    mid = left + int((right-left)/2)
    if list_num[mid] > target:
    right = mid - 1
    elif list_num[mid] < target:
    left = mid + 1
    elif list_num[mid] == target:
    right = mid - 1 #缩小right,逼近左侧边界
    if left >= len(list_num) or list_num[left] != target: #针对特殊的左侧边界,进行特殊的判断
    return -1
    return left

    def query_left_target_boundary_v2(list_num, target):
    left = 0
    right = len(list_num)
    while left < right:
    mid = left + int((right-left)/2)
    if list_num[mid] > target:
    right = mid
    elif list_num[mid] < target:
    left = mid + 1
    elif list_num[mid] == target:
    right = mid
    if left >= len(list_num) or list_num[left] != target:
    return -1
    return left

    #寻找右侧边界
    def query_right_target_boundary_v1(list_num, target):
    left = 0
    right = len(list_num) - 1
    while left <= right:
    mid = left + int((right-left)/2)
    if list_num[mid] > target:
    right = mid - 1
    elif list_num[mid] < target:
    left = mid + 1
    elif list_num[mid] == target:
    left = mid + 1 #缩小left,逼近右侧侧边界
    if right < 0 or list_num[right] != target: #针对特殊的右侧边界,进行特殊的判断
    return -1
    return right

    def query_left_target_boundary_v2(list_num, target):
    left = 0
    right = len(list_num)
    while left < right:
    mid = left + int((right-left)/2)
    if list_num[mid] > target:
    right = mid
    elif list_num[mid] < target:
    left = mid + 1
    elif list_num[mid] == target:
    left = mid + 1
    if right <= 0 or list_num[right - 1] != target:
    return -1
    return right - 1



    """
    剑指 Offer 53 - I. 在排序数组中查找数字 I
    统计一个数字在排序数组中出现的次数。

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

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

    """
    给定一个按照升序排列的整数数组nums, 和一个目标值target。找出给定目标值在数组的开始位置和结束位置(leetcode 34)
    """

    """
    解题思路:这道题和find_target_number类似,也是考虑求出目标值的左右边界
    """
    def find_target_first_end(nums, target):
    #找出左侧边界的索引
    left_index = find_left_index(nums, target)
    if left_index == -1:
    return [-1, -1]
    right_index = find_right_index(nums, target)
    return [left_index, right_index]

    def find_left_index(nums, target):
    left = 0
    right = len(nums)
    while left < right:
    mid = left + int((right - left) / 2)
    if nums[mid] >= target:
    right = mid
    else:
    left = mid + 1
    if left >= len(nums) or nums[left] != target:
    return -1
    return left

    def find_right_index(nums, target):
    left = 0
    right = len(nums)
    while left < right:
    mid = left + int((right - left) / 2)
    if nums[mid] <= target:
    left = mid + 1
    else:
    right = mid
    if right <= 0 or nums[right - 1] != target:
    return -1
    return right - 1

    if __name__ == "__main__":
    nums = [5,7,7,8,8,10]
    target = 10
    res = find_target_first_end(nums, target)
    print(res)


    解题思路:
    按照二分查找的方式,找到目标值的左右边界的索引 然后用右边界-左边界+1
    """
    class Solution(object):
    def search(self, nums, target):
    left = 0
    right = len(nums)
    target_left = -1
    target_right = -1
    #找出目标值的左侧边界
    while left < right:
    mid = left + int((right - left) / 2)
    if nums[mid] > target:
    right = mid
    elif nums[mid] < target:
    left = mid + 1
    elif nums[mid] == target:
    right = mid

    if left >= len(nums) or nums[left] != target:
    target_left = -1
    else:
    target_left = left
  • 相关阅读:
    苹果信息推送服务(Apple Push Notification Service)使用总结
    Xcode 相关路径总结
    微信红包随机算法 OC
    Xcode真机测试could not find developer disk image解决方法
    字典转模型 重写初始化方法
    Xcode 写代码没有补全提示解决:删缓存及显示隐藏文件命令
    按位与、或、异或等运算方法
    OC语言@property @synthesize和id
    iOS开发—Quartz2D简单介绍
    iOS开发—CoreLocation定位服务
  • 原文地址:https://www.cnblogs.com/tomorrow-hope/p/15476681.html
Copyright © 2011-2022 走看看