二分查找——leetcode 209 长度最小的连续子数组

"""
leetcode 209
求长度最小的连续子数组 target = 7, nums = [2,3,1,2,4,3] output=2

解题思路:
这个题可以采用滑动窗口的方法,他是窗口大小变化的一种窗口计算方法[在后续有单独的滑动窗口模块],时间复杂度为O(n);同时,这道题也可以采用二分查找方法
"""

#基于滑动窗口的方法
def search_min_length_array(nums, target):
left = 0
right = 0
ans = float('inf')
total = 0
while right < len(nums):
total += nums[right]
right += 1
while total >= target:
if total == target:
ans = min(ans, right - left)
total -= nums[left]
left += 1
return 0 if ans == float('inf') else ans


#基于二分查找的方法
def search_min_length_array_II(nums, target):
sums = [0]
for num in nums:
sums.append(sums[-1] + num)
#找到大于目标值得决策边界
right_index = search_right_index(sums, target)
#找到相差一个目标值的索引
ans = float('inf')
for index in range(right_index, len(sums)):
target2 = sums[index] - target
left_index = search_left_index(sums, target2, index)
if left_index == -1:
continue
else:
ans = min(ans, index - left_index)
return 0 if ans == float('inf') else ans


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


def search_left_index(sums, target, right_index):
left = 0
right = right_index
while left < right:
mid = left + int((right - left) / 2)
if sums[mid] == target:
return mid
elif sums[mid] > target:
right = mid
elif sums[mid] < target:
left = mid + 1

return -1



if __name__ == "__main__":
nums = [1,1,1,1,1,1,1,1]
target = 11
res = search_min_length_array_II(nums, target)
print(res)
原文地址:https://www.cnblogs.com/tomorrow-hope/p/15476891.html