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
  • 相关阅读:
    (一) kinect概述
    (五)摇杆/按钮/触摸板
    (四)Trigger
    (三)快速添加touch事件
    (二)简单触控
    Java程序设计当堂测试 9.20
    Java程序设计当堂测试感受
    暑假生活第八周总结
    暑假生活第七周总结
    暑假生活第六周总结
  • 原文地址:https://www.cnblogs.com/tomorrow-hope/p/15476681.html
Copyright © 2011-2022 走看看