# 循环访问数组 res = 0 week = [1,2,3,4,5,6,7] for i in range(n): res = res + week[i%7] + i//7 return res
快速判断奇偶
1 2
x&1 为1表示奇数
快速获取间隔的数组
1 2
a = [1,2,3,4,5,6,7,8] a[1:10:3] 每间隔3
快速计算斐波那契数列
1 2
import math math.factorial(3)
快速求中位数
1 2 3 4 5 6 7
# 奇数 n = len(nums1) if n & 1: return nums1[(n-1)//2] # 偶数 else: return (nums1[(n-1)//2] + nums1[(n-1)//2 + 1])/2
快速循环一个序列
1 2 3 4 5 6 7
nums = [1, 2, 3, 4] for i inrange(len(nums)): print(nums[i]) index = (i + 1) % len(nums) while index != i: print(nums[index]) index = (index + 1) % len(nums)
加油站[134]那道题
快速判断是否为素数
1 2
defis_prime(n): return n >= 2andall(n%i for i inrange(2, int(n**0.5) + 1))
for也可以这么搞
1 2 3 4 5 6 7
for i inrange(100): if i%2==0: xxx else: xxx else: xxxx
排序和字典排序
1 2 3
nums.sort() t = list(zip(numn1,nu8m2)) t.sort(key=lambda x:x[0])
from collections import defaultdict d = defaultdict(int) for i in s: d[i] = d[i] + 1 d_list = list(d.items()) d_list.sort(key=lambda x: -x[1]) print(d_list)
快速计算除数和余数
1 2 3
a,b=divmod(10,3) a=3 b=1
快速复制
a = [1,2,3]
b=a 这样的话a变了的话,b也会变
b=a[:] 这样就不会了
b=a=0
这样不会有问题的
连续求和快速初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
defcontinueSum(nums): target = 9 c = list(range(1, target)) sums = [c[0]] for i inrange(1, len(c)): sums.append(c[i] + sums[-1]) print(sums) result = [] for i inrange(len(sums)): for j inrange(i + 1, len(sums)): if i == 0: val = 0 else: val = sums[i - 1] print(i, j, sums[j] - val) continueSum([9, 4, 2, 3, 8, 0, 6])
如果要求i-j的和,则必须sums[j] - sum[i-1]
数组双循环
1 2 3
for i inrange(n): for j inrange(i+1,n+1): print()
快速前缀和初始化
1 2 3 4 5 6
nums = [1, 4, 8, 13] prefix = [0] for i in nums: prefix.append(prefix[-1] + i) # 求解 i-j的值 print(prefix[j+1]-prefix[i])
如下:
1 2 3 4 5
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: print(i, j) cnt += 1
计算两个索引之间的差值
1 2 3 4 5 6 7 8
arr = [1, 2] predix = [0] for i in arr: predix.append(predix[-1] + i) res = 0 for i inrange(len(arr)): for j inrange(i, len(arr)): print(i, j)
nums = [1,2,3,4,5] print(bisect.bisect_left(nums,12)) # 得到的值为5,但是没有5的索引的,因此会报错 index = bisect.bisect_left(array2, i + diff // 2) index = min(len(array2)-1, index) if array2[index] == i + diff // 2: return [i, i + diff // 2] # 通过将值插入后,判断位置,如果是=len()的话,那直接为len()-1。
二分查找中边界的设置
1 2 3 4 5 6 7 8 9 10 11
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
# 最大topk问题 import heapq defbigestK(arr, k): if k == 0: return [] else: l = [] for i in arr: iflen(l) < k: heapq.heappush(l, i) else: if i > l[0]:# 注意点 heapq.heappop(l) heapq.heappush(l, i) return l a = bigestK([1, 3, 5, 7, 2, 4, 6, 8], 4) print(a)
可以看到,heapq就是对一个list做操作而已,因此。最后动的还是列表。
可以简化写成如下:
1 2 3 4 5 6
for i in nums: if len(res) >= k: if i > res[0]: heapq.heappop(res) else: heapq.heappush(res, i)
# 最小tooK问题 defsmallestK(arr, k): if k == 0: return [] else: l = [] for i in arr: iflen(l) < k: heapq.heappush(l, -i) else: if -i > l[0]: # 注意点 heapq.heappop(l) heapq.heappush(l, -i) return [-i for i in l]
defmaxSlidingWindow2(nums, k): if k == 1: return nums else: ans = [] l = [] for i, j inenumerate(nums): if i < k: # 别写错 heapq.heappush(l, (-j, i)) else: while l and l[0][1] <= i - k:# 别写错 heapq.heappop(l) heapq.heappush(l, (-j, i)) if i >= k - 1:# 别写错 ans.append(-l[0][0]) return ans
这里注意为啥要取-的呢,因为我们只取一个数值,不会取前K个。
简单写法如下:
1 2 3 4 5 6 7 8 9
defmaxSlidingWindow3(nums, k): hp, ret = [], [] for i, j inenumerate(nums): while hp and hp[0][1] <= i - k: heapq.heappop(hp) heapq.heappush(hp, [-j, i]) if i >= k - 1: ret.append(-hp[0][0]) return ret
单调栈
1 2 3 4 5 6 7 8 9 10
heights = [2, 1, 5, 6, 2, 3] stack = [] n = len(heights) right_min = [n] * n for i in range(n): while stack and stack[-1][0] > heights[i]: val = stack.pop() right_min[val[1]] = i stack.append((heights[i], i)) # 求出右边最大的也是可以的
defmaxSlidingWindow(nums, k): q, ret = deque(), [] for i, j inenumerate(nums): while q and nums[q[-1]] < j: q.pop() if q and q[0] <= i - k: q.popleft() q.append(i) if i >= k - 1: ret.append(nums[q[0]]) return ret
defback(state, s): res.append(state[:]) for i inrange(len(s)): state.append(s[i]) back(state, s[i + 1:]) state.pop()
back([], nums) print(res)
这里注意在back中没使用到if条件,因为不需要使用到if条件,如果来了一句
1
这点在单词拆分 II中用到了,可以看下。
快速访问二维的list
下面介绍下访问二维的list的方法
1 2 3 4 5 6 7 8 9
matrix = [["1", "0", "1", "0", "0"], ["1", "0", "1", "1", "1"], ["1", "1", "1", "1", "1"], ["1", "0", "0", "1", "0"]] m = len(matrix) n = len(matrix[0]) max_k = 0 for i inrange(m): for j inrange(n): for k inrange(1, max(m - i, n - i)): c = [i[j:j + k] for i in matrix[i:i + k]] print(c)
res1 = [] res1 = [0] * 5 for i inrange(5): if i%2==0: res1.append(i) res1[i] = 4
上述得到的res1和res2结果是不一样的。
常见必备基础算法
快速幂
1 2 3 4 5 6 7 8 9 10
classSolution: defmyPow(self, x: float, n: int) -> float: if x == 0.0: return0.0 res = 1 if n < 0: x, n = 1 / x, -n while n: if n & 1: res *= x x *= x n >>= 1 return res
字典序
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: deflexicalOrder(self, n: int) -> List[int]: ans = [] num = 1 whilelen(ans) < n: while num <= n: # 不断进入下一层 ans.append(num) num *= 10 while num % 10 == 9or num > n: # 不断返回上一层 num //= 10 num += 1# 遍历该层下一个数 return ans