文章目录
前言
整理力扣刷题思路。
- 语言:python
- 题库:来自neetcode: link
一、预备知识
二、解题思路
1.二分法
二分法问题的解析:link
33.search-in-rotated-sorted-array
整数数组 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 。
你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
link
class Solution:
def search(self, nums: List[int], target: int) -> int:
l,r = 0,len(nums)-1
while l<=r:
mid = (l+r)//2
if nums[mid] == target:
return mid
if nums[l] < nums[mid]: #前半部分是有序的
if nums[mid] < target:
l = mid+1
else:
if nums[l] <= target:
r = mid-1
else:
l = mid+1
elif nums[l] > nums[mid]: #后半部分是有序的
if nums[mid] > target:
r = mid-1
else:
if nums[l] <= target:
r = mid-1
else:
l = mid+1
else:
l += 1
return -1
153.find-minimum-in-rotated-sorted-array
已知一个长度为 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 ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
link
class Solution:
def findMin(self, nums: List[int]) -> int:
n = len(nums)
if n==1:
return nums[0]
l,r = 0,n-1
while l<r:
#相当于没有旋转的升序数组
if nums[l] < nums[r]:
return nums[l]
mid = (l+r)//2
if nums[mid] >= nums[l]:
l = mid+1
else:
r = mid
return nums[l]
注意:这题的多次旋转有一点迷惑性,其实效果跟一次旋转是一样的
981.time-based-key-value-store/
设计一个基于时间的键值数据结构,该结构可以在不同时间戳存储对应同一个键的多个值,并针对特定时间戳检索键对应的值。
实现 TimeMap 类:
TimeMap() 初始化数据结构对象
void set(String key, String value, int timestamp) 存储给定时间戳 timestamp 时的键 key 和值 value。
String get(String key, int timestamp) 返回一个值,该值在之前调用了 set,其中 timestamp_prev <= timestamp 。如果有多个这样的值,它将返回与最大 timestamp_prev 关联的值。如果没有值,则返回空字符串(“”)。
class TimeMap:
def __init__(self):
self.map = defaultdict(list)
def set(self, key: str, value: str, timestamp: int) -> None:
self.map[key].append([timestamp,value])
def get(self, key: str, timestamp: int) -> str:
if not self.map[key]:
return ""
arr = self.map[key]
l,r = 0,len(arr)-1
if timestamp < arr[l][0]:
return ""
elif timestamp >= arr[r][0]:
return arr[r][1]
else:
while l<=r:
mid = (l+r)//2
tmp = int(arr[mid][0])
if timestamp == tmp:
return arr[mid][1]
elif timestamp < tmp:
r = mid-1
else:
l = mid+1
return arr[r][1]
# Your TimeMap object will be instantiated and called as such:
# obj = TimeMap()
# obj.set(key,value,timestamp)
# param_2 = obj.get(key,timestamp)
这一题实际上是在升序数组中寻找target,只要target刚好在两数之间,则返回较小的那一个数