classSolution: defhIndex(self, citations: List[int]) -> int: import bisect citations.sort() res = 0 for i inrange(1, len(citations)+1): index = bisect.bisect_left(citations, i) iflen(citations) - index >= i: res = max(res, i) return res
nums_set = Counter(nums) if k == 0: returnsum([i>1for i in nums_set.values()]) # 注意这里
nums.sort() diff_min, diff_max = nums[0], nums[-1] cnt = 0 for j in nums_set.keys(): index = bisect.bisect_left(nums, j+k) if index < len(nums): if nums[index] == j+k: cnt += 1 return cnt
classSolution: defreversePairs(self, record: List[int]) -> int: import bisect record = record[::-1] # 这步很重要 res = [] s = 0 for i in record: index = bisect.bisect_left(res, i) res[index:index] = [i] # bisect.insort(res, i)也可以 s = s + index return s
classSolution: defcountSmaller(self, nums: List[int]) -> List[int]: import bisect data = [] res = [] for i in nums[::-1]: index = bisect.bisect_left(data, i) data[index:index] = [i] #bisect.insort(data, i)也行 res.append(index) return res[::-1]
# 自己解法 classSolution(object): defsmallestDifference(self, a, b): """ :type a: List[int] :type b: List[int] :rtype: int """ import bisect a.sort() b.sort()
res = float("inf") for i in a: index = bisect.bisect_left(b, i) if index==len(b): diff = abs(i-b[index-1]) elif index == 0: diff = abs(i - b[0]) elif index>0: diff = min(abs(i-b[index-1]), abs(i-b[index])) res = min(diff, res) return res
classSolution: defshipWithinDays(self, weights: List[int], days: int) -> int: defget_shop_times(weights, v): need = 1 cur = 0 for i in weights: if cur + i > v: need += 1 cur = 0 cur += i return need
low = max(weights) high = sum(weights)
while low < high: # 注意的 mid = (high+low)//2 t = get_shop_times(weights, mid) if t <= days: # 压缩右边的 high = mid # 注意的 else: low = mid + 1 return low 或者 low<=high 然后 high=mid-1也可以的
classSolution: defmaxFrequency(self, nums: List[int], k: int) -> int: nums.sort() low = 0 high = len(nums) res = 0 prefix = [0] for i in nums: prefix.append(prefix[-1] + i) for i inrange(len(nums)): low = 0 high = i while low < high: mid = (low + high) >> 1 if nums[i] * (i - mid + 1) - prefix[i + 1] + prefix[mid] <= k: high = mid else: low = mid + 1 res = max(res, i - low + 1) return res
还有双指针的做法,具体如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution: defmaxFrequency(self, nums: List[int], k: int) -> int: nums.sort() i = ans = 0 # 问题转化一下,排序后 nums[j] * (j - i + 1) <= k + presum[j + 1] - presum[i] for j, num inenumerate(nums): k += num while k < num * (j - i + 1): k -= nums[i] i += 1 # 对于当前j最远的i ans = max(ans, j - i + 1) return ans
# 暴力 classSolution: defcountRangeSum(self, nums: List[int], lower: int, upper: int) -> int: import bisect prefix = [0] for i in nums: prefix.append(i + prefix[-1]) cnt = 0 for i inrange(len(nums)): for j inrange(i, len(nums)): if (prefix[j + 1] - prefix[i]) >= lower and (prefix[j + 1] - prefix[i]) <= upper: cnt += 1 return cnt # 通过 classSolution: defcountRangeSum(self, nums: List[int], lower: int, upper: int) -> int: res, pre, now = 0, [0], 0 for n in nums: now += n res += bisect.bisect_right(pre, now - lower) - bisect.bisect_left(pre, now - upper) bisect.insort(pre, now) return res # AC [通俗版] classSolution: defcountRangeSum(self, nums: List[int], lower: int, upper: int) -> int: sl = [] res = 0 pre_sum = [0] for i in nums: pre_sum.append(pre_sum[-1] + i) for x in pre_sum: res += bisect.bisect_right(sl, x - lower) - bisect.bisect_left(sl, x - upper) bisect.insort(sl, x) return res
# 我的解法 classSolution: defminOperations(self, nums: List[int], x: int) -> int: defget_prefix_sum(nums): prefix = [] for i in nums: val = prefix[-1] if prefix else0 prefix.append(i+val) return prefix
res = float("inf") for i inrange(len(nums)): nums2 = nums[0:i][::-1] + nums[i:][::-1] prefix = get_prefix_sum(nums2) print(prefix) if x in prefix: res = min(res, prefix.index(x)+1) return -1if res==float("inf") else res # 正确的 classSolution: defminOperations(self, nums: List[int], x: int) -> int: diff = sum(nums) - x if diff < 0: return -1 left = 0 right = 0 sm = 0 res = -1 while right < len(nums): sm += nums[right] while sm > diff: sm -= nums[left] left += 1 if sm == diff: res = max(res,right - left + 1) right += 1 return -1if res==-1elselen(nums)-res
classSolution: defminSubArrayLen(self, target: int, nums: List[int]) -> int: import bisect prefix = [0] for i in nums: prefix.append(prefix[-1] + i) if prefix[-1]<target: return0 res = float("inf") for i inrange(len(prefix)): index = bisect.bisect_left(prefix, prefix[i] + target) if index != len(prefix): res = min(index - i, res) return0if res==len(prefix) else res
也可以使用滑窗解法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution: defminSubArrayLen(self, s: int, nums: List[int]) -> int: ifnot nums: return0 n = len(nums) ans = n + 1 start, end = 0, 0 total = 0 while end < n: total += nums[end] while total >= s: ans = min(ans, end - start + 1) total -= nums[start] start += 1 end += 1 return0if ans == n + 1else ans
# 超时 classSolution: defshortestSubarray(self, nums: List[int], k: int) -> int: n = len(nums) res = float("inf") for left inrange(len(nums)): right = left sm =0 while right < n: sm += nums[right] while sm >= k: res = min(res, right - left + 1) sm -= nums[left] left += 1 right += 1 return -1if res==float("inf") else res # 超时2:这个思路要弄懂 模仿区间和的个数区间和的个数来的 classSolution: defshortestSubarray(self, nums: List[int], k: int) -> int: import bisect res = float("inf") cnt = 0 pre_sum = [[0, cnt]] for i inrange(1, len(nums) + 1): pre_sum.append([pre_sum[-1][0] + nums[i - 1], i]) pre_sum.sort() for i in pre_sum: cur_val = i[0] index = bisect.bisect_left(pre_sum, [cur_val + k, 0]) for j inrange(index, len(pre_sum)): if j <= len(nums) and pre_sum[j][0] >= cur_val + k and pre_sum[j][1] - i[1] >= 0: res = min(res, pre_sum[j][1] - i[1]) if res==float("inf"): return -1 return res # 超时的原因在于有多个循环,其实看下面的结果也是有多个循环, 也就是1个for里面加了两个while, 不过计算的时候,是通过单调队列来做的,减少了滑窗计算的时间而已。这里和滑窗窗口的最大值是一样的。 classSolution: defshortestSubarray(self, nums: List[int], k: int) -> int: import collections prefix = [0] for i in nums: prefix.append(prefix[-1] + i) stack = collections.deque() ans = len(nums) + 1 for x, y inenumerate(prefix): while stack and y <= prefix[stack[-1]]: stack.pop() while stack and y - prefix[stack[0]] >= k: ans = min(ans, x - stack.popleft()) stack.append(x) return ans if ans < len(nums) + 1else -1
# 解法1,使用双指针 classSolution: deffindMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: m = len(nums1) n = len(nums2) lens = m + n prev = -1 now = -1 num1_index = 0 num2_index = 0 for i inrange(lens//2+1): prev = now if num1_index<m and (num2_index>=n or nums1[num1_index]<nums2[num2_index]): now = nums1[num1_index] num1_index += 1 else: now = nums2[num2_index] num2_index += 1 if lens & 1 == 0: return (prev + now)/2 else: return now # 解法2:使用二分查找 classSolution: deffindMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: n1 = len(nums1) n2 = len(nums2) if n1 > n2: return self.findMedianSortedArrays(nums2, nums1)
k = (n1 + n2 + 1) // 2 left = 0 right = n1 while left < right: m1 = left + (right - left) // 2 m2 = k - m1 # if nums1[m1] < nums2[m2 - 1]: # 注意 left = m1 + 1 else: right = m1
m1 = left # 算出的m是第2个数,如果是&1=1的话,直接取m-1,不是的话,取m-1和m的均值 m2 = k - m1 c1 = max(float('-inf') if m1 <= 0else nums1[m1 - 1], float('-inf') if m2 <= 0else nums2[m2 - 1]) # 情况1,容易写错为m1 if (n1 + n2) % 2 == 1: return c1
c2 = min(float('inf') if m1 >= n1 else nums1[m1], float('inf') if m2 >= n2 else nums2[m2]) # 情况2
return (c1 + c2) / 2 # 自己做法 A = [1] B = [2] nums = [] left, right = 0, 0 while left < len(A) and right < len(B): if A[left] < B[right]: nums.append(A[left]) left += 1 else: nums.append(B[right]) right += 1 if left >= len(A): nums.extend(B[right:]) if right >= len(B): nums.extend(A[left:]) print(nums)
defdfs(temp, x,y): if x<0or x>=len(temp) or y<0or y>=len(temp[0]): returnFalse if temp[x][y]==0: returnFalse if x==len(temp)-1and y==len(temp[0])-1and temp[x][y]==1: returnTrue temp[x][y] = 0 for i,j in [[x+1,y],[x,y+1],[x-1,y],[x,y-1]]: if dfs(temp,i,j): returnTrue # dfs(temp,i,j): 直接这么写的话是错误的 returnFalse
grid_list = sum(grid, []) grid_list = sum(grid, []) low = min(grid_list) high = max(grid_list) while low < high: mid = (low + high) >> 1 temp = [[1if j <= mid else0for j in i] for i in grid] if dfs(temp, 0, 0): high = mid else: low = mid + 1 return low
classSolution(object): defminAbsoluteSumDiff(self, nums1, nums2): """ :type nums1: List[int] :type nums2: List[int] :rtype: int """ import bisect temp = [abs(nums1[i] - nums2[i]) for i inrange(len(nums1))] abs_sum = sum(temp)
nums11 = sorted(nums1)
res = abs_sum
for i, j inenumerate(nums2): index = bisect.bisect(nums11, j) if index < len(nums11): res = min(res, abs_sum - abs(nums1[i]-nums2[i]) + abs(nums11[index]-nums2[i])) if index > 0: res = min(res, abs_sum - abs(nums1[i]-nums2[i]) + abs(nums11[index-1]-nums2[i])) return res% (10**9+7)
for i in array1: index = bisect.bisect_left(array2, i + diff // 2) index = min(len(array2)-1, index) #dasdsdsa if array2[index] == i + diff // 2: return [i, i + diff // 2] return []
classSolution: defminOperations(self, target: List[int], arr: List[int]) -> int: posTa = {} for i, t inenumerate(target): posTa[t] = i posAr = [] for i, a inenumerate(arr): if a in posTa: posAr.append(posTa[a]) # 算出来出现的索引就可以了,然后就是求解了 stk = [] for x in posAr: if stk and x <= stk[-1]: idx = bisect_left(stk, x) stk[idx] = x else: stk.append(x) returnlen(target) - len(stk)
classSolution: defcountNegatives(self, grid: List[List[int]]) -> int: end = len(grid[0]) i = 0 res = 0 while i < len(grid): if grid[i][-1]<0: index = bisect.bisect_right([-j for j in grid[i]],0) res += len(grid[0]) - index i = i + 1 return res