過擬合的緣由:node
過擬合的解決方案:python
方法一: bitmap排序(要求無重複數據)算法
bitmap就是每一位存一個數字,一個byte有8個bit,能夠存8個數據。1M內存能夠存:8x1024X1024 = 8,388,608的數據。 api
而後順序遍歷bitmap便可取出排好序的數據。#Bitmap
class Bitmap():
def __init__(self,max):
'肯定所需數組個數'
self.size = int ((max + 31 - 1) / 31)
self.array = [0 for i in range(self.size)]
def bitindex(self,num):
'肯定數組中元素的位索引'
return num % 31
def set(self,num):
'將元素所在的位置1'
elemindex = num // 31
byteindex = self.bitindex(num)
ele = self.array[elemindex]
self.array[elemindex] = ele | (1 << byteindex)
def test(self,i):
'檢測元素存在的位置'
elemindex = i // 31
byteindex = self.bitindex(i)
if self.array[elemindex] & (1 << byteindex):
return True
return False
if __name__ == '__main__':
Max = 110
suffle_array = [51, 100 ,2, 4, 34]
result = []
bitmap = Bitmap(Max)
for c in suffle_array:
bitmap.set(c)
for i in range(Max+1):
if bitmap.test(i):
result.append(i)
print('原始數組爲: %s' % suffle_array)
print('排序後的數組爲: %s' % result)
複製代碼
題目:從1億個整數裏找出100個最大的數 方法一:堆排序數組
方法二:多路歸併app
注意以上merge時候的方法是循環比較的,假設有n個元素,每一個須要比較k次,複雜度爲O(nk)。更好的辦法使用最小堆實現,具體的方法和下面算法題中合併K個列表同樣。函數
思路:開一個數組存放結果,依次比較兩個list元素的大小,直到一個list爲空,剩下的加入res便可post
def merge(nums1, nums2):
res = []
while nums1 and nums2:
if nums1[0]<nums2[0]:
res.append(nums1.pop(0))
else:
res.append(nums2.pop(0))
res = res+nums1+nums2
return res
print(merge([1,2,3,4],[3,4,5,6,7]))
複製代碼
注意這種思路很重要學習
能夠利用最小堆完成,時間複雜度是O(nklogk),具體過程以下:測試
重複下列步驟n*k次:
初始化最小堆的時間複雜度O(k),總共有kn次循環,每次循環調整最小堆的時間複雜度是O(logk),因此總的時間複雜度是O(knlogk)
思路和合並list同樣
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
res = ListNode(None)
node = res
while l1 and l2:
if l1.val<l2.val:
node.next,l1 = l1,l1.next
else:
node.next,l2 = l2,l2.next
node = node.next
if l1:
node.next = l1
else:
node.next = l2
return res.next
複製代碼
思路和合並list同樣
def mergeKLists(self, lists):
""" :type lists: List[ListNode] :rtype: ListNode """
heap = []
for ln in lists:
if ln:
heap.append((ln.val, ln))
dummy = ListNode(0)
cur = dummy
heapq.heapify(heap)
while heap:
valu, ln_index = heapq.heappop(heap)
cur.next = ln_index
cur = cur.next
if ln_index.next:
heapq.heappush(heap, (ln_index.next.val, ln_index.next))
return dummy.next
複製代碼
class Tree:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
def inorder(root):
stack = []
result = []
cur = root
while stack or cur:
if cur:
stack.append(cur)
cur = cur.left
else:
cur = stack.pop()
result.append(cur.val)
cur = cur.right
return result
def preorder(root): ## 前序遍歷
stack = []
result = []
cur = root
while stack or cur:
if cur:
result.append(cur.val)
stack.append(cur.right)
cur = cur.left
else:
cur = stack.pop()
return result
def postorder(root): ## 後序遍歷
stack = []
result = []
cur = root
while stack or cur:
if cur:
result.append(cur.val)
stack.append(cur.left)
cur = cur.right
else:
cur = stack.pop()
return result[::-1]
def levelOrder(root): #層次遍歷
if not root:
return []
result = []
cur = root
queue = [cur]
while queue:
cur = queue.pop(0)
result.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
return result
tree = Tree(1)
tree.left = Tree(2)
tree.left.left = Tree(4)
tree.left.right = Tree(5)
tree.right = Tree(3)
tree.right.left = Tree(6)
tree.right.right = Tree(7)
print(preorder(tree))
print(inorder(tree))
print(postorder(tree))
print(levelOrder(tree))
複製代碼
適用於筆試的時候
利用python的庫進行二分查找:bisect_left
:數據的左插入區間,bisect_right
:數據的右插入區間
from bisect import bisect_left, bisect_right
def find(A, data):
index = bisect_left(A, data)
if index != len(A) and A[index] == data :
return index
return None
A = [1,2,2,2,2,3,3,3,3]
index = find(A, 2)
print(index)
複製代碼
from bisect import bisect_left, bisect_right
def find(A,data):
return bisect_right(A,data) - bisect_left(A, data)
A = [1,2,2,2,2,3,3,3,3]
res = find(A, data = 2)
print(res)
複製代碼
from bisect import bisect_left, bisect_right
def find(A, min, max):
return bisect_left(A, min), bisect_right(A, max)
A = [1,2,2,2,2,3,3,3,3]
l, r = find(A, min = 0.1, max = 2.5)
print(r-l)
複製代碼
dirs =[(0 ,1) ,(1 ,0) ,(0 ,-1) ,(-1 ,0)] # 當前位置四個方向的偏移量
path =[] # 存找到的路徑
def mark(maze ,pos): # 給迷宮maze的位置pos標"2"表示「訪問過了」
maze[pos[0]][pos[1]] =2
def passable(maze ,pos): # 檢查迷宮maze的位置pos是否可通行
if pos[0] >=len(maze) or pos[1]>=len(maze[0]) or pos[0] <0 or pos[1] <0 or maze[pos[0]][pos[1]]==1 or maze[pos[0]][pos[1]]==2:
return False
return True
def maze_dfs(maze ,start ,end):
if start==end:
print(start)
return
st= []
mark(maze ,start)
st.append(start) # 入口和方向0的序對入棧
while st!= [] : # 走不通時回退
pos =st.pop() # 取棧頂及其檢查方向
for i in range(4): # 依次檢查未檢查方向,算出下一位置
nextp = pos[0] + dirs[i][0], pos[1] + dirs[i][1]
if nextp==end:
st.append(pos)
st.append(end)
print(st) # 到達出口,打印位置
return
if passable(maze , nextp): # 遇到未探索的新位置
st.append(pos) # 原位置和下一方向入棧
mark(maze ,nextp)
st.append(nextp) # 新位置入棧
break # 退出內層循環,下次迭代將以新棧頂做爲當前位置繼續
print("找不到路徑")
if __name__ == '__main__':
#0表示能夠走通,1表示不能夠走通,2表示走過的位置
maze = [[0, 1, 0, 0, 1],
[0, 1, 0, 1, 0],
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 1, 0]]
start = (0 ,0)
end = (4 ,4)
maze_dfs(maze ,start,end)
複製代碼