小 trick
overlap条件:start1 < end2 and end1 > start2
在DFS中我们说关键点是递归以及回溯,在BFS中,关键点则是状态的选取和标记
树算法
Binary Indexed Tree BIT 树状数组
class BIT:
def __init__(self, n):
self.n = n + 1
self.sums = [0] * self.n
def update(self, i, delta):
while i < self.n:
self.sums[i] += delta
i += i & (-i) # = i & (~i + 1) 用于追踪最低位的1
def prefixSum(self, i):
res = 0
while i > 0:
res += self.sums[i]
i -= i & (-i)
return res
def rangeSum(self, s, e):
return self.prefixSum(e) - self.prefixSum(s - 1)
Binary Search Tree
class Node(object):
def __init__(self, data):
self.left = None
self.right = None
self.data = data
def 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 = data
def search(self, data, parent=None):
if data < self.data:
if self.left is None:
return None, None
return self.left.search(data, self)
elif data > self.data:
if self.right is None:
return None, None
return self.right.search(data, self)
else:
return self, parent
Trie
import collections
class TrieNode():
def __init__(self):
self.children = collections.defaultdict(TrieNode)
self.isEnd = False
class Trie():
def __init__(self):
self.root = TrieNode()
def insert(self, word):
node = self.root
for w in word:
node = node.children[w]
node.isEnd = True
def search(self, word):
node = self.root
for w in word:
# dict.get() 找不到的话返回None
node = node.children.get(w)
if not node:
return False
return node.isEnd
线段树
class SegmentTree(object):
def __init__(self, nums, s=None, e=None): # build
self.lo, self.hi = s, e
self.left, self.right = None, None
self.mid = (self.lo+self.hi)/2
self.val = 0
if self.hi < self.lo:
return
elif self.hi == self.lo:
self.val = nums[self.lo]
else: # self.lo < self.hi
self.left = SegmentTree(nums, self.lo, self.mid)
self.right = SegmentTree(nums, self.mid+1, self.hi)
self.val = self.left.val + self.right.val
def update(self, i, val): # modify
if i == self.lo == self.hi:
self.val = val
else:
if i <= self.mid:
self.left.update(i, val)
else:
self.right.update(i, val)
self.val = self.left.val + self.right.val
def sumRange(self, i, j): # query
if i == self.lo and j == self.hi: # equal
return self.val
elif self.lo > j or self.hi < i: # not intersect
return 0
else: # intersect
if i > self.mid: # all at the right sub tree
return self.right.sumRange(i, j)
elif j <= self.mid: # all at the left sub tree
return self.left.sumRange(i, j)
else: # some at the right & some at the left
return 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.val
elif self.lo > i or self.hi < i:
return 0
else:
if i > self.mid: # right
return self.right.get(i)
else: # left
return 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 += 1
nums[i], nums[hi] = nums[hi], nums[i]
return i
def 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+1
else:
hi = mid-1
nums = [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 = 0
for j in range(i):
if not compare(nums[j], nums[tmp]):
tmp = j
nums[tmp], nums[i-1] = nums[i-1], nums[tmp]
return nums
quick sort, in-place
def quick_sort(nums, l, r):
if l >= r:
return
pos = 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 += 1
nums[i], nums[hi] = nums[hi], nums[i]
return i
arr = [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 for