题
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
m,n=len(matrix),len(matrix[0])
m_l,m_r=0,m-1
n_l,n_r=0,n-1
#m_m=0
while m_l<m_r:
m_m=(m_l+m_r)//2
if matrix[m_m][-1]==target:
return True
elif matrix[m_m][-1]<target:
m_l=m_m+1
else:
m_r=m_m
while n_l<n_r:
n_m=(n_l+n_r)//2
if matrix[m_l][n_m]==target:
return True
elif matrix[m_l][n_m]<target:
n_l=n_m+1
else:
n_r=n_m-1
return True if matrix[m_l][n_l]==target else False
![](https://img.haomeiwen.com/i14913526/f7cac7ffb582b2d4.png)
下面的题与标解相差较大
整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
class Solution:
def search(self, nums: List[int], target: int) -> int:
left,right=0,len(nums)-1
while left<right:
mid=(left+right)//2
if nums[mid]>nums[left]:
if nums[mid]<target:
left=mid+1
elif nums[mid]==target:
return mid
else:
if nums[left]>target:
left=mid+1
elif nums[left]==target:
return left
else:
right=mid-1
else:
if nums[mid]==nums[left]:
ans=left if nums[left]==target else -1
ans =right if nums[right]==target else ans
#print(left,right)
return ans
if nums[mid]>target:
right=mid-1
elif nums[mid]==target:
return mid
else:
if nums[right]>target:
left=mid+1
elif nums[right]==target:
return right
else:
right=mid-1
'''
if nums[mid]<target and nums[left]:
left=mid+1
elif nums[mid]==target:
return mid
else:
if nums[left]<target:
right=mid-1
elif nums[left]==target:
return left
else:
left=mid+1
'''
ans=left if nums[left]==target else -1
ans =right if nums[right]==target else ans
#print(left,right)
return ans
![](https://img.haomeiwen.com/i14913526/9b10e466335f085f.png)
标解
class Solution:
def search(self, nums: List[int], target: int) -> int:
if not nums:
return -1
l, r = 0, len(nums) - 1
while l <= r:
mid = (l + r) // 2
if nums[mid] == target:
return mid
if nums[0] <= nums[mid]:
if nums[0] <= target < nums[mid]:
r = mid - 1
else:
l = mid + 1
else:
if nums[mid] < target <= nums[len(nums) - 1]:
l = mid + 1
else:
r = mid - 1
return -1
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-
array/solution/sou-suo-xuan-zhuan-pai-xu-shu-zu-by-leetcode-solut/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
对深入理解二分有帮助
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
if len(nums)==0:
return [-1,-1]
left,right=0,len(nums)-1
for i in range(2):
tl,tr=0,right
while tl<tr:
mid=(tl+tr)//2 if i==0 else (tl+tr+1)//2
#mid=(tl+tr)//2
if nums[mid]==target:
if i==0:
#print('0 {}'.format(mid))
tr=mid
else:
#print('1 {}'.format(mid))
tl=mid
elif nums[mid]>target:
tr=mid-1
else:
tl=mid+1
if i==0:
left=tl
else:
#print("hi")
right=tr
return [left,right] if nums[left]==target else [-1,-1]
关于优化时间复杂度和空间复杂度的想法
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
#cost.append(0)
#ans,n=cost[:2],len(cost)
a,b=cost[:2]
n=len(cost)
for i in cost[2:]:
a,b=b,min(a,b)+i
return min(a,b)
![](https://img.haomeiwen.com/i14913526/71333add5d758848.png)
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
class Solution:
def findMin(self, nums: List[int]) -> int:
left,right=0,len(nums)-1
if nums[-1]>=nums[0]:
return nums[0]
while left<right:
mid=(left+right)//2
if nums[mid]<nums[0]:
right=mid
else:
left=mid+1
return nums[left]
![](https://img.haomeiwen.com/i14913526/286f81bfed0c85bb.png)
网友评论