标签:参考资料 没有 第一个 min 空间复杂度 部分 ret 关系 bool
不积跬步,无以至千里;不积小流,无以成江海。
内容主要是个人学习使用,题目分类以及部分参考资料来自于CyC的博客,非常感谢大佬,题目来源于LeetCode,非常感谢本站支持。
二分查找又称折半查找,顾名思义就是每查找比较一次,就会去掉一半的不匹配项,重复执行此步骤直到找到目标元素或者不可以在分割
实现?int sqrt(int x)?函数。
计算并返回?x?的平方根,其中?x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
? 由于返回类型是整数,小数部分将被舍去。
解题思路:
计算平方根可以采用多种方法,具体可参考LeetCode官方,
代码实现
class Solution:
def mySqrt(self, x: int) -> int:
if (x <= 1): # 处理0,1特殊情况
return x;
left = 1
right = x // 2 # 确定区间
while left <= right:
mid = left + (right-left) // 2
num = mid * mid
if num > x:
right = mid - 1
elif num < x:
left = mid + 1
elif num == x:
return mid
return right
给你一个排序后的字符列表letters
,列表中只包含小写英文字母。另给出一个目标字母?target
,请你寻找在这一有序列表里比目标字母大的最小字母。
在比较时,字母是依序循环出现的。举个例子:
target = ‘z‘
并且字符列表为letters = [‘a‘, ‘b‘]
,则答案返回‘a‘
示例:
输入:
letters = ["c", "f", "j"]
target = "a"
输出: "c"
输入:
letters = ["c", "f", "j"]
target = "c"
输出: "f"
解题思路:
target
代码实现
class Solution:
def nextGreatestLetter(self, letters: List[str], target: str) -> str:
left = 0
right = len(letters) - 1
while left <= right:
mid = left + (right - left) // 2
if letters[mid] > target:
right = mid - 1
elif letters[mid] < target:
left = mid + 1
else:
left = mid + 1
return letters[left] if left < len(letters) else letters[0]
给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数。
示例 1:
输入: [1,1,2,3,3,4,4,8,8]
输出: 2
示例 2:
输入: [3,3,7,7,10,11,11]
输出: 10
注意: 您的方案应该在 O(log n)时间复杂度和 O(1)空间复杂度中运行。
解题思路:
[1,1,2,2,3,3,4,5,5]
,该数组分割后前[1,1,2,2]
,后为[3,4,5,5]
,由于都是偶数个,所以必定有一组是不含单一元素的,我们只需要比较中间元素和前一元素是否相等,不想等的则是正确一组,反之是需要下次查找[3,3,7,7,10,11,11]
,该数组分割后前[3,3,7]
,后为[10,11,11]
,由于都是奇数个,所以不能确定那一组到底是包含单一元素,我们仍然通过比较中间元素和前一元素是否相等,则相等则表示那一组是正确的,反之不正确。代码实现
class Solution:
def singleNonDuplicate(self, nums: List[int]) -> int:
left = 0
right = len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
tag = len(nums[:mid]) % 2 == 0 # 判断分割的左侧是不是偶数对
if tag:
if nums[mid] == nums[mid - 1]:
right = mid - 1
else:
left = mid + 1
else:
if nums[mid] == nums[mid - 1]:
left = mid + 1
else:
right = mid - 1
return nums[right]
假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用?bool isBadVersion(version)?接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
示例:
给定 n = 5,并且 version = 4 是第一个错误的版本。
调用 isBadVersion(3) -> false
调用 isBadVersion(5)?-> true
调用 isBadVersion(4)?-> true
所以,4 是第一个错误的版本。?
解题思路:
mid
版本是正确的,则表示错误版本处于[mid+1,right]
,不断缩减右区间mid
版本是错误的,则表示错误版本处于[left,mid]
,不断缩减左区间代码实现
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
left = 1
right = n
while left < right:
mid = left + (right - left) // 2
if isBadVersion(mid):
right = mid
else:
left = mid + 1
return left
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组?[0,1,2,4,5,6,7] 可能变为?[4,5,6,7,0,1,2]?)。
请找出其中最小的元素。你可以假设数组中不存在重复元素
示例 1:
输入: [3,4,5,1,2]
输出: 1
示例 2:
输入: [4,5,6,7,0,1,2]
输出: 0
解题思路:
[4, 5, 6, 7, 0, 1, 2], mid = 3, nums[mid] = 7, nums[-1] = 2
, 故 nums[mid] > nums[-1]
,说明数组旋转后较小的一部分升序序列在mid右边,更新区间:left = mid + 1
;[6, 7, 1, 2, 3, 4, 5], mid = 3, nums[mid] = 2, nums[-1] = 5
,故 nums[mid] < nums[-1]
,说明数组旋转后较小的一部分升序序列在mid左边,更新区间:right = mid - 1
。代码实现
class Solution:
def findMin(self, nums: List[int]) -> int:
left = 0
right = len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] > nums[-1]:
left = mid + 1
else:
right = mid - 1
return nums[left]
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是?O(log n) 级别。
如果数组中不存在目标值,返回?[-1, -1]。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例?2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
解题思路:
代码实现
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
left = 0
right = len(nums) - 1
ret = []
while left <= right:
mid = left + (right - left) // 2
if nums[mid] > target:
right = mid - 1
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
if left == len(nums):
ret.append(-1)
else:
ret.append(left if nums[left] == target else -1)
left = 0
right = len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] > target:
right = mid - 1
elif nums[mid] < target:
left = mid + 1
else:
left = mid + 1
if left == 0:
ret.append(-1)
else:
ret.append(left-1 if nums[left-1] == target else -1)
return ret
标签:参考资料 没有 第一个 min 空间复杂度 部分 ret 关系 bool
原文地址:https://www.cnblogs.com/ydongy/p/13090437.html