日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python leetcode_Leetcode 常用算法 Python 模板

發(fā)布時間:2023/12/15 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python leetcode_Leetcode 常用算法 Python 模板 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

小 trick

overlap條件:start1 < end2 and end1 > start2

在DFS中我們說關(guān)鍵點是遞歸以及回溯,在BFS中,關(guān)鍵點則是狀態(tài)的選取和標記

樹算法

Binary Indexed Tree BIT 樹狀數(shù)組

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)算法

每個節(jié)點選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))"""經(jīng)過上述操作,將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 = [] # 存儲最小生成樹結(jié)果# 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加入到堆中,并能夠?qū)崿F(xiàn)用heappop從其中動態(tài)取出最小值。關(guān)于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,第一次循環(huán)就是('A','D',5) append into resres.append((v1, v2, w))# 再找與d相鄰的點,如果沒有在heap中,則應(yīng)用heappush壓入堆內(nèi),以加入排序行列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(迪杰斯特拉)算法是典型的單源最短路徑算法,用于計算一個節(jié)點到其他所有節(jié)點的最短路徑
  • 以起始點為中心向外層層擴展,直到擴展到終點為止
  • 要求圖中不存在負權(quán)邊

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()# 已經(jīng)確定了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.從任意一條單邊路徑開始。所有兩點之間的距離是邊的權(quán),如果兩點之間沒有邊相連,則權(quán)為無窮大。

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 # 記錄新路徑的前驅(qū) 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# 奇數(shù)位置需要比較char# 偶數(shù)位置直接加一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)

鏈表相關(guān)

優(yōu)雅地遍歷鏈表

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+1, hi = mid,返回lo,lo=0, hi=n

# 等價于 bisect # 保證 選的數(shù)>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 # 保證 選的數(shù)>=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

二分最優(yōu)問題

都是 (lo+hi)//2, helper(mid) >= K, hi = mid-1, lo = 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 - 當前方塊到結(jié)束點的預(yù)估移動代價[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

數(shù)學方法

素數(shù)篩法

# 1不是素數(shù),最小的質(zhì)數(shù)是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

求因數(shù)

# Given a list A, return all prime factors of elements in A def getAllFactors(A):factors = []for x in A:facs = []# 篩法優(yōu)化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說明有殘余的質(zhì)數(shù),not facs說明x本身是質(zhì)數(shù)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

求多個數(shù)的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的所有g(shù)raycode # 用于遍歷所有情況 # 0000 # 0001 # 0011 # 0010 # 0110 # 0111 # 0101 # 0100 # 1100 # 1101 # 1111 # 1110 # 1010 # 1011 # 1001 # 1000

專用方法

單調(diào)棧

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

二維數(shù)組前綴和

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"))

優(yōu)雅地先序遍歷

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))

總結(jié)

以上是生活随笔為你收集整理的python leetcode_Leetcode 常用算法 Python 模板的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。