python leetcode_Leetcode 常用算法 Python 模板

5026f856358c3bc54418e5b609ce57d3.png

小 trick

overlap条件:start1 < end2 and end1 > start2

在DFS中我们说关键点是递归以及回溯,在BFS中,关键点则是状态的选取和标记

树算法

Binary Indexed Tree BIT 树状数组

class BIT:def __init__(self, n):self.n = n + 1self.sums = [0] * self.ndef update(self, i, delta):while i < self.n:self.sums[i] += deltai += i & (-i) # = i & (~i + 1) 用于追踪最低位的1def prefixSum(self, i):res = 0while i > 0:res += self.sums[i]i -= i & (-i)return resdef rangeSum(self, s, e):return self.prefixSum(e) - self.prefixSum(s - 1)

Binary Search Tree

class Node(object):def __init__(self, data):self.left = Noneself.right = Noneself.data = datadef insert(self, data):if self.data:if data < self.data:if self.left is None:self.left = Node(data)else:self.left.insert(data)elif data > self.data:if self.right is None:self.right = Node(data)else:self.right.insert(data)else:self.data = datadef search(self, data, parent=None):if data < self.data:if self.left is None:return None, Nonereturn self.left.search(data, self)elif data > self.data:if self.right is None:return None, Nonereturn self.right.search(data, self)else:return self, parent

Trie

import collectionsclass TrieNode():def __init__(self):self.children = collections.defaultdict(TrieNode)self.isEnd = Falseclass Trie():def __init__(self):self.root = TrieNode()def insert(self, word):node = self.rootfor w in word:node = node.children[w]node.isEnd = Truedef search(self, word):node = self.rootfor w in word:# dict.get() 找不到的话返回Nonenode = node.children.get(w)if not node:return Falsereturn node.isEnd

线段树

class SegmentTree(object):def __init__(self, nums, s=None, e=None):  # buildself.lo, self.hi = s, eself.left, self.right = None, Noneself.mid = (self.lo+self.hi)/2self.val = 0if self.hi < self.lo:returnelif self.hi == self.lo:self.val = nums[self.lo]else:  # self.lo < self.hiself.left = SegmentTree(nums, self.lo, self.mid)self.right = SegmentTree(nums, self.mid+1, self.hi)self.val = self.left.val + self.right.valdef update(self, i, val):  # modifyif i == self.lo == self.hi:self.val = valelse:if i <= self.mid:self.left.update(i, val)else:self.right.update(i, val)self.val = self.left.val + self.right.valdef sumRange(self, i, j):  # queryif i == self.lo and j == self.hi:  # equalreturn self.valelif self.lo > j or self.hi < i:  # not intersectreturn 0else:  # intersectif i > self.mid:  # all at the right sub treereturn self.right.sumRange(i, j)elif j <= self.mid:  # all at the left sub treereturn self.left.sumRange(i, j)else:  # some at the right & some at the leftreturn self.left.sumRange(i, self.mid) + self.right.sumRange(self.mid+1, j)def get(self, i):if self.lo == self.hi == i:return self.valelif self.lo > i or self.hi < i:return 0else:if i > self.mid:  # rightreturn self.right.get(i)else:  # leftreturn self.left.get(i)

排序算法

快速选择

quick select

def partition(nums, lo, hi):i, x = lo, nums[hi]for j in range(lo, hi):if nums[j] <= x:nums[i], nums[j] = nums[j], nums[i]i += 1nums[i], nums[hi] = nums[hi], nums[i]return idef quick_select(nums, lo, hi, k):while lo < hi:mid = partition(nums, lo, hi)if mid == k:return nums[k]elif mid < k:lo = mid+1else:hi = mid-1nums = [54, 26, 93, 17, 77, 31, 44, 55, 20]
for i in range(len(nums)):print(quick_select(nums, 0, len(nums)-1, i))

selection sort

def selection_sort(nums):for i in range(len(nums), 0, -1):tmp = 0for j in range(i):if not compare(nums[j], nums[tmp]):tmp = jnums[tmp], nums[i-1] = nums[i-1], nums[tmp]return nums

quick sort, in-place

def quick_sort(nums, l, r):if l >= r:returnpos = partition(nums, l, r)quick_sort(nums, l, pos-1)quick_sort(nums, pos+1, r)def partition(nums, lo, hi):i, x = lo, nums[hi]for j in range(lo, hi):if nums[j] <= x:nums[i], nums[j] = nums[j], nums[i]i += 1nums[i], nums[hi] = nums[hi], nums[i]return iarr = [4, 2, 1, 23, 2, 4, 2, 3]
quick_sort(arr, 0, len(arr)-1)
print(arr)

bubble sort

def bubble_sort(nums):for i in reversed(range(len(nums))):for j in range(i-1):if not compare(nums[j], nums[j+1]):nums[j], nums[j+1] = nums[j+1], nums[j]return nums

insertion sort

def insertion_sort(nums):for i in range(len(nums)):pos, cur = i, nums[i]while pos > 0 and not compare(nums[pos-1], cur):nums[pos] = nums[pos-1]  # move one-step forwardpos -= 1nums[pos] = curreturn nums

merge sort

def merge_sort(nums):nums = mergeSort(nums, 0, len(nums)-1)return str(int("".join(map(str, nums))))def mergeSort(nums, l, r):if l > r:returnif l == r:return [nums[l]]mid = (r+l)//2left = mergeSort(nums, l, mid)right = mergeSort(nums, mid+1, r)return merge(left, right)def merge(l1, l2):res, i, j = [], 0, 0while i < len(l1) and j < len(l2):if not compare(l1[i], l2[j]):res.append(l2[j])j += 1else:res.append(l1[i])i += 1res.extend(l1[i:] or l2[j:]) # 喵 return res

图论算法

拓扑排序

两个defaultdict 一个graph,一个in_degree

from collections import defaultdictdef findOrder(numCourses, prerequisites):graph = defaultdict(list)in_degree = defaultdict(int)for dest, src in prerequisites:graph[src].append(dest)in_degree[dest] += 1zero_degree = [k for k, v in in_degree.items() if v == 0]res = []while zero_degree:node = zero_degree.pop(0)res.append(node)for child in graph[node]:in_degree[child] -= 1if in_degree[child] == 0:zero_degree.append(child)  # 同时也说这个元素该删除了return res

普利姆(Prime)算法

每个节点选cost最小的边

from collections import defaultdict
import heapqdef prim(vertexs, edges):adjacent_vertex = defaultdict(list)for v1, v2, length in edges:adjacent_vertex[v1].append((length, v1, v2))adjacent_vertex[v2].append((length, v2, v1))"""经过上述操作,将edges列表中各项归类成以某点为dictionary的key,其value则是其相邻的点以及边长。如下:defaultdict(<type 'list'>, {'A': [(7, 'A', 'B'), (5, 'A', 'D')],'C': [(8, 'C', 'B'), (5, 'C', 'E')],'B': [(7, 'B', 'A'), (8, 'B', 'C'), (9, 'B', 'D'), (7, 'B', 'E')],'E': [(7, 'E', 'B'), (5, 'E', 'C'), (15, 'E', 'D'), (8, 'E', 'F'), (9, 'E', 'G')],'D': [(5, 'D', 'A'), (9, 'D', 'B'), (15, 'D', 'E'), (6, 'D', 'F')],'G': [(9, 'G', 'E'), (11, 'G', 'F')],'F': [(6, 'F', 'D'), (8, 'F', 'E'), (11, 'F', 'G')]})"""res = []  # 存储最小生成树结果# vertexs是顶点列表,vertexs = list("ABCDEFG") == = > vertexs = ['A', 'B', 'C', 'D', 'E', 'F', 'G']visited = set(vertexs[0])# 得到adjacent_vertexs_edges中顶点是'A'(nodes[0]='A')的相邻点list,即adjacent_vertexs['A']=[(7,'A','B'),(5,'A','D')]adjacent_vertexs_edges = adjacent_vertex[vertexs[0]]# 将usable_edges加入到堆中,并能够实现用heappop从其中动态取出最小值。关于heapq模块功能,参考python官方文档heapq.heapify(adjacent_vertexs_edges)while adjacent_vertexs_edges:# 得到某个定点(做为adjacent_vertexs_edges的键)与相邻点距离(相邻点和边长/距离做为该键的值)最小值w, v1, v2 = heapq.heappop(adjacent_vertexs_edges)if v2 not in visited:# 在used中有第一选定的点'A',上面得到了距离A点最近的点'D',举例是5。将'd'追加到used中visited.add(v2)# 将v1,v2,w,第一次循环就是('A','D',5) append into resres.append((v1, v2, w))# 再找与d相邻的点,如果没有在heap中,则应用heappush压入堆内,以加入排序行列for next_vertex in adjacent_vertex[v2]:if next_vertex[2] not in visited:heapq.heappush(adjacent_vertexs_edges, next_vertex)return res# test
vertexs = list("ABCDEFG")
edges = [("A", "B", 7), ("A", "D", 5),("B", "C", 8), ("B", "D", 9),("B", "E", 7), ("C", "E", 5),("D", "E", 15), ("D", "F", 6),("E", "F", 8), ("E", "G", 9),("F", "G", 11)]print("edges:", edges)
print("prim:", prim(vertexs, edges))

Dijkstra[单源最短路径算法]

  • Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径
  • 以起始点为中心向外层层扩展,直到扩展到终点为止
  • 要求图中不存在负权边

76929f3588e66cd74ea178100db67a52.png

b829849d1895844a0f93c4b3597dfef2.png
import sysdef dijkstra(graph):n = len(graph)dist = [sys.maxsize] * ndist[0] = 0  # 自己和自己距离为0visited = set()def minDistance():# 找到还没确定的里面距离最小的min_ans, min_index = min((dis, i)for i, dis in enumerate(dist) if i not in visited)return min_indexfor _ in range(n):min_index = minDistance()# 已经确定了visited.add(min_index)for v in range(n):if v not in visited and graph[min_index][v] > 0:# graph[min_index][v] > 0 表示存在这个路径new_dist = dist[min_index] + graph[min_index][v]if dist[v] > new_dist:  # 表示值得被更新dist[v] = new_distprint(dist)# Driver program
graph = [[0, 4, 0, 0, 0, 0, 0, 8, 0],[4, 0, 8, 0, 0, 0, 0, 11, 0],[0, 8, 0, 7, 0, 4, 0, 0, 2],[0, 0, 7, 0, 9, 14, 0, 0, 0],[0, 0, 0, 9, 0, 10, 0, 0, 0],[0, 0, 4, 14, 10, 0, 2, 0, 0],[0, 0, 0, 0, 0, 2, 0, 1, 6],[8, 11, 0, 0, 0, 0, 1, 0, 7],[0, 0, 2, 0, 0, 0, 6, 7, 0]]dijkstra(graph)

Floyd[任意两点间的最短路径]

a.从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。

b.对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是更新它。

Inf = 65535  # 代表无穷大
arr = [[0, 10, Inf, Inf, Inf, 11, Inf, Inf, Inf],  # 邻接矩阵[10, 0, 18, Inf, Inf, Inf, 16, Inf, 12],[Inf, 18, 0, 22, Inf, Inf, Inf, Inf, 8],[Inf, Inf, 22, 0, 20, Inf, Inf, 16, 21],[Inf, Inf, Inf, 20, 0, 26, Inf, 7, Inf],[11, Inf, Inf, Inf, 26, 0, 17, Inf, Inf],[Inf, 16, Inf, 24, Inf, 17, 0, 19, Inf],[Inf, Inf, Inf, 16, 7, Inf, 19, 0, Inf],[Inf, 12, 8, 21, Inf, Inf, Inf, Inf, 0]]n = len(arr)  # 邻接矩阵大小
path = [[-1]*n for _ in range(n)]for k in range(n): # k在第一层for i in range(n):for j in range(n):if(arr[i][j] > arr[i][k]+arr[k][j]):  # 两个顶点直接较小的间接路径替换较大的直接路径arr[i][j] = arr[i][k]+arr[k][j]path[i][j] = k  # 记录新路径的前驱
for x in arr:print(x)
print()
for x in path:print(x)

字符串算法

KMP

class Solution(object):def strStr(self, haystack, needle):""":type haystack: str:type needle: str:rtype: int"""if not needle: return 0# build nextnext = [0]*len(needle)l, r = 0, 1while r < len(needle):if needle[l] == needle[r]:next[r] = l+1l, r = l+1, r+1elif l: l = next[l-1]else: r += 1# find idxl, r = 0, 0while r < len(haystack):if needle[l] == haystack[r]:if l == len(needle)-1:return r-ll, r = l+1, r+1elif l: l = next[l-1]else: r += 1return -1

Rabin-Karp Hash

class RabinKarpHash:def __init__(self, base, mod=int(1e9+7)):self.base = baseself.mod = moddef hash(self, arr):h = 0for val in arr:h = ((h * self.base) + val) % self.modreturn hdef roll(self, origin_hash, drop_val, new_val, max_base):h = origin_hash - (drop_val * max_base % self.mod)h = ((h*self.base)+new_val+self.mod)%self.modreturn hdef get_max_base(self, length):ret = 1for i in range(length-1):ret = (ret*self.base) % self.modreturn ret

Manacher’s Algorithm

https://www.geeksforgeeks.org/manachers-algorithm-linear-time-longest-palindromic-substring-part-4/

def findLongestPalindromicString(text):length = len(text)if length == 0:returnN = 2*length+1    # Position countL = [0] * NL[0] = 0L[1] = 1C = 1     # centerPositionR = 2     # centerRightPositioni = 0    # currentRightPositioniMirror = 0     # currentLeftPositionmaxLPSLength = 0maxLPSCenterPosition = 0diff = -1for i in range(2, N):# get currentLeftPosition iMirror for currentRightPosition iiMirror = 2*C-iL[i] = 0  # 初始化范围diff = R - i  # 当前位置离上一个边界的距离# If currentRightPosition i is within centerRightPosition Rif diff > 0:  # 利用对称性获取L[i]的最小值L[i] = min(L[iMirror], diff)# 计算当前palindrome长度while (True):# 边界条件con1 = (i + L[i]) < N and (i - L[i]) > 0if (not con1):break# 奇数位置需要比较char# 偶数位置直接加一con2 = (i + L[i]) % 2 == 1left_radius = int((i + L[i] + 1) / 2)right_radius = int((i - L[i] - 1) / 2)con31 = 0 <= left_radius and left_radius < lengthcon32 = 0 <= right_radius and right_radius < lengthcon3 = con31 and con32 and (text[left_radius] == text[right_radius])if(con2 or con3):L[i] += 1else:breakif L[i] > maxLPSLength:        # Track maxLPSLengthmaxLPSLength = L[i]maxLPSCenterPosition = i# 触及上一个边界的话选择centerif i + L[i] > R:C = i# 更新边界为当前的边界R = i + L[i]# Uncomment it to print LPS Length array# printf("%d ", L[i]);start = int((maxLPSCenterPosition - maxLPSLength) / 2)end = int(start + maxLPSLength)print(text[start:end])# Driver program
text1 = "babcbabcbaccba"
findLongestPalindromicString(text1)

链表相关

优雅地遍历链表

while head:head = head.next

standard linked list reversing

class Solution:def reverseList(self, head):cur, prev = head, Nonewhile cur:cur.next, cur, prev = prev, cur.next, cur  # standard reversingreturn prev

merge sort list

class Solution(object):def merge(self, h1, h2):dummy = tail = ListNode(None)while h1 and h2:if h1.val < h2.val:tail.next, tail, h1 = h1, h1, h1.nextelse:tail.next, tail, h2 = h2, h2, h2.nexttail.next = h1 or h2return dummy.nextdef sortList(self, head):if not head or not head.next:return headpre, slow, fast = None, head, headwhile fast and fast.next:pre, slow, fast = slow, slow.next, fast.next.nextpre.next = Nonereturn self.merge(self.sortList(head), self.sortList(slow))

二分

标准二分(bisect)

永远是lo = mid+1hi = mid,返回lo,lo=0, hi=n

# 等价于 bisect
# 保证 选的数>k 严格大于
def bisect_right(a, x, lo=0, hi=None):lo, hi = 0, nwhile lo < hi:mid = (lo+hi)//2if x < a[mid]:hi = mid # disgard equals partelse:lo = mid+1return lo# bisect_left is more useful at hand, since it returns the exact index of the element being looked up if it is present in the list
# 保证 选的数>=k 大于等于
def bisect_left(a, x, lo=0, hi=None):lo, hi = 0, nwhile lo < hi:mid = (lo+hi)//2if a[mid] < x:lo = mid+1  # disgard equals partelse:hi = midreturn lo>>> import bisect
>>> bisect.bisect_left([1,2,3], 2)
1
>>> bisect.bisect_right([1,2,3], 2)
2

范围都是[0-n]

import bisect
print(bisect.bisect_left([1, 2, 3], -1))  # 0
print(bisect.bisect_left([1, 2, 3], 0))  # 0
print(bisect.bisect_left([1, 2, 3], 1))  # 0
print(bisect.bisect_left([1, 2, 3], 2))  # 1
print(bisect.bisect_left([1, 2, 3], 3))  # 2
print(bisect.bisect_left([1, 2, 3], 4))  # 3print(bisect.bisect([1, 2, 3], -1))  # 0
print(bisect.bisect([1, 2, 3], 0))  # 0
print(bisect.bisect([1, 2, 3], 1))  # 1
print(bisect.bisect([1, 2, 3], 2))  # 2
print(bisect.bisect([1, 2, 3], 3))  # 3
print(bisect.bisect([1, 2, 3], 4))  # 3

二分最优问题

都是 (lo+hi)//2helper(mid) >= Khi = mid-1lo = mid+1

# 最大
# 找到最大的mid使得helper(mid)>=K
lo, hi = 1, sum(sweetness)
while lo <= hi:# 找到最大的mid使得count>=Kmid = (lo+hi)//2if helper(mid) >= K:  # mid还可以再大一点lo = mid+1else:hi = mid-1return hi # 返回的是hi# 最小
# 找到最小的mid使得helper(mid)>=K
lo, hi = 1, sum(sweetness)
while lo <= hi:# 找到最大的mid使得count>=Kmid = (lo+hi)//2if helper(mid) >= K:  # mid还可以再大一点hi = mid-1else:lo = mid+1return lo # 返回的是lo

搜索算法

并查集 Union-Find Set (General)

class UF:def __init__(self, n):self.parent = list(range(n+1))def find(self, i):if self.parent[i] != i:  # 用i来判断self.parent[i] = self.find(self.parent[i])  # 路径压缩return self.parent[i]def union(self, x, y):self.parent[self.find(x)] = self.find(y)

回溯法通用模板

def combine(self, n, k):ans = []def helper(cur, start):if len(cur) == k:ans.append(cur[:])returnelse:for i in range(start+1, n+1):cur.append(i)helper(cur, i)cur.pop()helper([], 0)return ans

A星算法核心公式

F = G + H

F - 方块的总移动代价 G - 开始点到当前方块的移动代价 H - 当前方块到结束点的预估移动代价[heuristic]

import heapqdef heuristic(a, b):return (b[0] - a[0]) ** 2 + (b[1] - a[1]) ** 2def astar(array, start, destination):n, m = len(array), len(array[0])dirs = [(0, 1), (0, -1), (1, 0), (-1, 0),(1, 1), (1, -1), (-1, 1), (-1, -1)]visited = set()came_from = {}gscore = {start: 0}fscore = {start: heuristic(start, destination)}queue = []heapq.heappush(queue, (fscore[start], start))while queue:score, cur_pos = heapq.heappop(queue)if cur_pos == destination:data = []while cur_pos in came_from:data.append(cur_pos)cur_pos = came_from[cur_pos]return datavisited.add(cur_pos)for i, j in dirs:x, y = cur_pos[0] + i, cur_pos[1] + jneibor = (x, y)g = gscore[cur_pos]h = heuristic(cur_pos, neibor)f = g+hif (not(0 <= x < n and 0 <= y < m)  # 不能越界or array[x][y] == 1  # 墙不能走or(neibor in visited and f >= gscore.get(neibor, 0))):  # 还不如从0直接过来continueif g < gscore.get(neibor, 0) or neibor not in [i[1]for i in queue]:came_from[neibor] = cur_posgscore[neibor] = gfscore[neibor] = g + heuristic(neibor, destination)heapq.heappush(queue, (fscore[neibor], neibor))return Falsenmap = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]print(astar(nmap, (0, 0), (10, 13)))def heuristic(a, b):(x1, y1) = a(x2, y2) = breturn abs(x1 - x2) + abs(y1 - y2)def a_star_search(graph, start, goal):frontier = PriorityQueue()frontier.put(start, 0)came_from = {}cost_so_far = {}came_from[start] = Nonecost_so_far[start] = 0while not frontier.empty():current = frontier.get()if current == goal:breakfor next in graph.neighbors(current):new_cost = cost_so_far[current] + graph.cost(current, next)if next not in cost_so_far or new_cost < cost_so_far[next]:cost_so_far[next] = new_costpriority = new_cost + heuristic(goal, next)frontier.put(next, priority)came_from[next] = currentreturn came_from, cost_so_far

数学方法

素数筛法

# 1不是素数,最小的质数是2
# Prime table
maxInteger = 1000000
prime = [True]*maxInteger
prime[0] = False
prime[1] = False
for i in range(2, (int)(math.sqrt(maxInteger)+1)):if prime[i]:for j in range(i*i, maxInteger, i):prime[j] = False

求因数

# Given a list A, return all prime factors of elements in A
def getAllFactors(A):factors = []for x in A:facs = []# 筛法优化k, d = 0, primes[k]while d * :if x % d == 0:while x % d == 0:x //= dfacs.append(d)k += 1d = primes[k]# 特判,x>1说明有残余的质数,not facs说明x本身是质数if x > 1 or not facs:facs.append(x)factors.append(facs)

黄金比例求斐波那契

class Solution:def fib(self, N):golden_ratio = (1 + 5 ** 0.5) / 2return int((golden_ratio ** N + 1) / 5 ** 0.5)

$$ phi=frac{1+sqrt{5}}{2} approx 1.61803 $$

快速幂

def fastExpMod(a, b):res = 1while b:if (b & 1):# ei = 1, then mulres *= ab >>= 1# b, b^2, b^4, b^8, ... , b^(2^n)a *= areturn res

牛顿法

class Solution:def mySqrt(self, x):r = x + 1  # avoid dividing 0while r*r > x:r = int((r+x/r)/2)  # newton's methodreturn r

GCD

def gcd(a, b):while b:a, b = b, a % breturn a

求多个数的GCD

def arr_gcd(self, A):gcd = A[0]for a in A:while a:gcd, a = a, gcd % areturn gcd

graycode

def grayCode(n):res = [0]i = 0while i < n:  # 从2的0次方开始,next_base = 1 << ires_inv = [x + next_base for x in reversed(res)]res.extend(res_inv)i += 1return res# 长度为4的所有graycode
# 用于遍历所有情况
# 0000
# 0001
# 0011
# 0010
# 0110
# 0111
# 0101
# 0100
# 1100
# 1101
# 1111
# 1110
# 1010
# 1011
# 1001
# 1000

专用方法

单调栈

def foo(nums):st = []res = [0]*len(nums)for i, x in enumerate(nums):while st and nums[st[-1]] < x:idx = st.pop()res[idx] = i-idxst.append(i)return res

slide window

一个for 一个 while 不容易出错

class Window:def __init__(self):self.count = collections.Counter()self.reserve = 0def add(self, x):if self.count[x] == 0: # 从效果上来判断self.reserve += 1self.count[x] += 1def remove(self, x):self.count[x] -= 1if self.count[x] == 0: #self.reserve -= 1class Solution(object):def lengthOfLongestSubstringKDistinct(self, A, K):if not A or not len(A) or not K:return 0win = Window()ans = l = 0# 一个for 一个 while 不容易出错for r, x in enumerate(A):win.add(x)while win.reserve > K:win.remove(A[l])l += 1ans = max(r-l+1, ans)return ans

二维数组前缀和

n, m = len(grid), len(grid[0])
pre_sum = [[0]*(m+1) for _ in range(n+1)]for i in range(n):for j in range(m):pre_sum[i][j] = pre_sum[i][j-1] + pre_sum[i-1][j] - pre_sum[i-1][j-1] + grid[i][j]def get_sum(x0, y0, x1, y1):return pre_sum[x1][y1] - pre_sum[x0-1][y1] - pre_sum[x1][y0-1] + pre_sum[x0-1][y0-1]def helper(size):cur_max_sum = max(get_sum(x, y, x+size-1, y+size-1)for x in range(n-size+1) for y in range(m-size+1))return cur_max_sum

RMQ/ST[Sparse Table]算法

import mathclass ST:def __init__(self, arr):self.arr = arrself.n = n = len(arr)self.m = m = int(math.log(n, 2))self.maxsum = maxsum = [[0]*(m+1) for _ in range(n)]self.minsum = minsum = [[0]*(m+1) for _ in range(n)]for i, x in enumerate(arr):maxsum[i][0] = minsum[i][0] = xfor j in range(m):for i in range(n):k = i + (1 << j)if(k < n):maxsum[i][j+1] = max(maxsum[i][j], maxsum[k][j])minsum[i][j+1] = min(minsum[i][j], minsum[k][j])def get_max(self, a, b):k = int(math.log(b-a+1, 2))# 一头一尾return max(self.maxsum[a][k], self.maxsum[b-(1 << k)+1][k])def get_min(self, a, b):k = int(math.log(b-a+1, 2))return min(self.minsum[a][k], self.minsum[b-(1 << k)+1][k])arr = [3, 4, 5, 7, 8, 9, 0, 3, 4, 5]
st = ST(arr)
print(st.get_max(0, 9))  # 9
print(st.get_max(6, 9))  # 5
print(st.get_min(0, 9))  # 0
print(st.get_min(0, 4))  # 3

LZ77

def compress(message):win_size = 10  # 窗口长度pointer = 0  # 指针,初始指向第一个位置compressed_message = []while pointer < len(message):matched_length = 0  # 匹配到的长度# 窗口的corner casewindow = message[max(pointer - win_size, 0):pointer]# 能找到的最大长度while window.find(message[pointer:pointer + matched_length + 1]) != -1:matched_length += 1e = pointer + matched_length# window.find(message[start:end]) 相对窗口的offset# max(start - win_size, 0) 整个窗口的offset# first:在整个字符串中的offsetfirst_appear = window.find(message[pointer:e]) + max(pointer - win_size, 0)item = (pointer - first_appear, matched_length, message[e])compressed_message.append(item)pointer += matched_length + 1return compressed_messageprint(compress("abcdbbccaaabaeaaabaee"))

优雅地先序遍历

def preorder(self, root):if (not root):return ["null"]return [str(root.val)]+self.preorder(root.left)+self.preorder(root.right)def serialize(self, root):return ",".join(self.preorder(root))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/245218.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

画瀑布图_常见的招财风水画之含义

点击上方【觉悟法华】关注 风水画是指利于风水的字画&#xff0c;能起到招财、旺运、化煞等等的风水作用。那么&#xff0c;常见的招财风水画有哪些含义&#xff1f;大鹏展翅图&#xff1a;大鹏展翅图&#xff0c;通常挂在书房或者客厅&#xff0c;给人以一种“鹏程万里”、积极…

荣耀play4 pro怎么升级鸿蒙系统,华为鸿蒙系统手机型号有哪些

华为鸿蒙系统支持的手机型号有很多&#xff0c;如果你想第一时间升级鸿蒙系统&#xff0c;需要申请内测后&#xff0c;才能够下载安装升级哦&#xff01;不知道如何操作的小伙伴们&#xff0c;一起来看看趣丁网带来的华为鸿蒙os2.0系统怎么升级教程吧&#xff01;一、华为鸿蒙系…

shell脚本中取消高亮显示_Linux中强大的top命令

top命令算是最直观、好用的查看服务器负载的命令了。它实时动态刷新显示服务器状态信息&#xff0c;且可以通过交互式命令自定义显示内容&#xff0c;非常强大。在终端中输入top&#xff0c;回车后会显示如下内容&#xff1a;一、系统信息统计前五行是系统整体状态的统计信息展…

body onload 控制窗口大小 html,HTML5 对各个标签的定义与规定:body的介绍

HTML5 对各个标签的定义与规定&#xff1a;body的介绍2019年07月25日| 萬仟网IT编程| 我要评论本文主要介绍body标签... 12-06-21body元素就是就是html文档的主内容标签。可设置属性onafterprint 在打印文档之后运行脚本onbeforeprint 在文档打印之前运行脚本onbeforeonload 在…

html5手机电商网页设计代码_Html5网站制作,干货!20个视觉体验和内容俱佳的优秀网页设计...

如何创建一个网页&#xff1f;“Html5网站制作”和“灵感干货&#xff01;20个视觉、体验和内容俱佳的优秀网页设计”有什么关系和内在关联&#xff1f;在图片方面&#xff0c;有三个具体方案&#xff1a;图片地图、Css Sprites、内联图片三种&#xff0c;最值得关注的是 Css S…

2021 高考 成绩查询,精准预测!2021全国大学录取分数线表查询

高考分数对应大学层次等级随着各大高校的疯狂扩招&#xff0c;大学的门槛近年来越来越低&#xff0c;虽然还不至于达到普及大学的程度&#xff0c;但对于成绩不是太差的高中生而言&#xff0c;上大学确实是一件轻松加愉快的事情。在高考总分750的情况下&#xff0c;文科生551分…

python图像处理opencv_使用Python+OpenCV进行图像处理(二)| 视觉入门

【前言】图像预处理对于整个图像处理任务来讲特别重要。如果我们没有进行恰当的预处理&#xff0c;无论我们有多么好的数据也很难得到理想的结果。 本篇是视觉入门系列教程的第二篇。整个视觉入门系列内容如下&#xff1a; 基本的图像处理与滤波技术。 从特征检测到人脸检测。 …

html文本设置float,css怎么float(浮动)?

在css中&#xff0c;浮动是一种使元素脱离文档流的方法&#xff0c;会使元素向左或向右移动&#xff0c;其周围的元素也会重新排列。Float(浮动)&#xff0c;往往是用于图像&#xff0c;但它在布局时一样非常有用。浮动是一种非常有用的布局方式&#xff0c;它能够改变页面中对…

字符动图_手把手教你做一个python+matplotlib的炫酷的数据可视化动图

1.数据可视化动图&#xff0c;是数据可视化的高级显示&#xff0c;最近很流行。2.比如下面将告诉你如何制作一个如下的数据可视化动图。3.例&#xff1a;3.1 准备一组数据&#xff0c;虚拟的csv资料&#xff0c;对应关系如下4个项目&#xff1a;namegroupyearvaluename&#xf…

weblogic jms消息 删除_消息队列与消息中间件概述:消息中间件核心概念与技术选型...

什么是消息&#xff1f;“消息”是在两台计算机间传送的数据单位。消息可以非常简单&#xff0c;例如只包含文本字符串&#xff1b;也可以更复杂&#xff0c;可能包含嵌入对象。什么是队列&#xff1f;队列(Queue)队列是一种先进先出(FIFO)的数据结构。什么是消息队列&#xff…

伽马分布极大似然估计_一文通俗解释极大似然估计

我们都知道机器学习的大致流程是通过建立一个合理的模型学习现有数据集&#xff0c;然后通过该模型去完成特定的任务。其中每个模型都包含自身的一组特定参数&#xff0c;而这组参数决定着模型的本身。但这里存在一个很关键的一个问题&#xff0c;就是我们如何去找到一组参数使…

python3.5安装pygame_python怎么安装pygame

Pygame 是一种流行的 Python 包&#xff0c;用于编写游戏-鼓励学生学习编程&#xff0c;同时创建有趣的东西。 Pygame 在新窗口中显示图形&#xff0c;因此它将 无法在 WSL 的命令行方法下运行。 但是&#xff0c;如果您通过本教程中所述的 Microsoft Store 安装了 Python&…

所属的用户_关于chmod(变更用户对此文件的相关权限)超详细说明,小白秒懂

Linux下一切都是文件,通过ls -l或者别名ll可以查看文件的详细信息:drwxr-xr-x 第一个字符d指的是目录文件;第2-4个字符rwx&#xff1a;指的是u(user,owner)对这个文件具有可读可写可执行的权限;第5-7字符r-x&#xff1a;指的是g(group)对这个文件具有可读可执行权限&#xff1b…

cad线性标注命令_CAD常用标注快捷键和命令

点击上方 “CAD自学网 ” → 点击右上角“...” → 点选“设为星标 ★ ”为CAD自学网加上星标&#xff0c;即可及时收到干货啦&#xff01;左下角阅读原文看CAD视频站长推荐&#xff1a;1、CAD2014快速精通进阶提高教程&#xff1a;点击查看 2、室内设计全屋定制全套视频教程&…

计算机怎么设置网络共享,局域网共享设置,教您电脑怎么设置局域网共享

前两天&#xff0c;遇到位朋友说他刚买了台新的电脑&#xff0c;加上原来家里原有的两台电脑了&#xff0c;就三台了&#xff0c;现在想要三台电脑都能够进行一个共享职员的这么设置&#xff0c;就是不知道如何在局域网里怎么设置共享&#xff0c;下面&#xff0c;小编就来跟大…

html引用外部导入式css文件夹,css文件内引用外部资源文件的相对路径

1.default.css文件内容(位于css文件夹下)&#xff1a;.ClassName .ClassName .ClassName.page-sidebar .sidebar-search .submit {--该图片相对于css文件所在的位置。不是使用本css文件的html文件位置。background-image: url(../image/search-icon.png);}2.使用本css文件的htm…

京东五星电器送扫地机器人_家电也流行“套餐”,京东五星电器吹响国庆家装“集结号”...

“70吋超薄激光电视、大容量多门法式冰箱、烘干一体滚筒洗衣机、蒸烤一体机、扫地机器人……”一系列的新房采购清单让宿迁的谭小姐直呼头痛&#xff0c;“挑选品牌和型号&#xff0c;比较价格&#xff0c;还要想着跟装修风格是否搭配&#xff0c;好浪费时间。”在线下实体店迎…

c++设置单元格填充色_格式函数text,设置自定义格式的万金油

在日常的数据处理统计中&#xff0c;我们知道&#xff0c;数据格式标准统一&#xff0c;是很重要的前提&#xff0c;如果数据混乱&#xff0c;那么&#xff0c;在后期的数据处理分析&#xff0c;excel就会耍脾气出错的。所以设置好数据格式&#xff0c;是相当重要的。今天&…

生成html_听说你不会用Python将字符串生成PDF?来,我教你!

这是恋习Python推荐的第118篇好文来源&#xff1a;Python爬虫与算法作者&#xff1a;jclian笔者在今天的工作中&#xff0c;遇到了一个需求&#xff0c;那就是如何将Python字符串生成PDF。比如&#xff0c;需要把Python字符串‘这是测试文件’生成为PDF, 该PDF中含有文字‘这是…

大学计算机基础python第二次作业_python第二次作业-titanic数据集练习

一、读入titanic.xlsx文件&#xff0c;按照教材示例步骤&#xff0c;完成数据清洗。 titanic数据集包含11个特征&#xff0c;分别是&#xff1a; Survived:0代表死亡&#xff0c;1代表存活 Pclass:乘客所持票类&#xff0c;有三种值(1,2,3) Name:乘客姓名 Sex:乘客性别 Age:乘客…