LC 34: Find 1st and Last Position of Element in Sorted Array
题目要求:在排序过(非递减)的array - nums中找出target value 的start index 和 end index, 且必须用O(logN) 的二分查找法做出
思路:双指针的红蓝染色法
1. 假设target 在[L, R] 中, 使用while (L <= R) loop, 让左指针一直向右移动, 直到 right < left pointer 时可以知道:左边红色区域的数字肯定是 < target ; 右边蓝色区域的数字肯定是 >= target的

class Solution:
def lower_bound(self, nums, target) -> int:
l, r = 0, len(nums) - 1
while (l <= r):
mid = (l + r) // 2
if (target > nums[mid]): # 为什么这个要写到前面: 因为我们想让left 一直往右移
l = mid + 1
else:
r = mid - 1
return l # 然后当r < l 的时候, 我们确保r及左边的数是小于target的, l及右边的数是大于等于target的, l是右边区域最小的
def searchRange(self, nums: List[int], target: int) -> List[int]:
# 假设target在 [L,R]中
start_idx = self.lower_bound(nums, target)
# 如果start_idx = nums的长度 或者直到l被挪到最右边的上面的数值也不等于target,
# 那就说明整个array中没有target
if(start_idx == len(nums) or nums[start_idx] != target):
return [-1,-1]
# target已经找到了,继续看target的下一个数, 也就是target+1,的前面一个index
end_idx = self.lower_bound(nums, target + 1) - 1
return [start_idx, end_idx]
LC977: 有序数组的平方
- 双指针: i = 0, j = nums.size - 1
- 设置新的array = ret, 指针为k,k = nums.size - 1, 从后往前走, 因为题目要求最大的在最后
- while (i <= j) , 比较nums[i]的方大还是nums[j]的方大, 新的array, ret[k] = 更大的数的方
- 注意 i和j的增减, k一直都-=1,因为在向左边移动
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
ret = [float('-inf')] * len(nums) #建立新的数组, 大小 = nums.size
i = 0
j = len(nums) - 1
k = len(nums) - 1 # 因为新的数组是由大到小, 最后一位是最大的, 所以k是size - 1
while (i <= j): #当 i <= j 时,i可以移动到array中的最后一位, 所以i = j
if (nums[i]**2 > nums[j]**2): #如果nums[i]的平方大, 从ret[k] 也就是从ret的最后一位开始, ret[k] = nums【i】的方
ret[k] = nums[i]**2
i += 1
else:
ret[k] = nums[j]**2 # 不然ret【k】就是nums【j】的方
j -= 1
k -= 1 # 因为题目要最大的方后面, k从后往前走的
return ret
LC209: 长度最小的子数组
题目要求: 找出subLen最短的subarray, 使得subarray的和 >= target value
思路: sliding window
1. i和j都从idx = 0开始, j在前走, 更新sum += nums [ j ]
2. 当得到的sum 一直都大于或等于target的时候, 算出每次的subLen, 更新最短的subLen(这里是ret), 让 idx i 向右挪动,看右边的会不会有新的组合满足要求
3. 如果直到 j 走到最后, ret都没有更新,那说明array中没有满足要求的, return 0
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
# 这道题是典型的sliding window题目
# 我们设置i和j两个指针, 从头开始向右走,j走在前面nums[j]一直相加
i = 0
j = 0
sum = 0 # sum = nums【j】一直相加的和
ret = float('Inf') # ret为最后return的最短的subarray的长度 subLen = j-i+1
# for loop 中得到nums[j]的和
for j in range(len(nums)):
sum += nums[j]
while(sum >= target):
subLen = j - i + 1 # sliding window的长度,j和i之间的距离
ret = min(ret, subLen) # 求最短长度
# 为什么i要向右边移动
# 因为我们想subLen的长度为最小,所以当我们发现目前sum已经 > 或 = target了,就不考虑目前的nums[i]了
sum -= nums[i]
i += 1 # 我们得让i向右边挪,看右边会不会有新的组合满足要求
if(ret == float('Inf')): # 如果ret还是之前的Inf没变过, 说明array中没有>= target的, return 0
return 0
else:
return ret
|LC977: 有序数组的平方 | LC209: 长度最小的子数组&spm=1001.2101.3001.5002&articleId=139145238&d=1&t=3&u=9baada604beb411290354a5b53643478)
558

被折叠的 条评论
为什么被折叠?



