python面試總結4(算法與內置數據結構)

算法與內置數據結構

  • 經常使用算法和數據結構
    1. sorted
    2. dict/list/set/tuple
  • 分析時間/空間複雜度
  • 實現常見數據結構和算法
數據結構/算法 語言內置 內置庫
線性結構 list(列表)/tuple(元祖) array(數組,不經常使用)/collection.namedtuple
鏈式結構 collections.deque(雙端隊列)
字典結構 dict(字典) collections.Counter(計數器)/OrderedDict(有序字典)
集合結構 set(集合)/frozenset(不可變集合)
排序算法 sorted
二分算法 bisect模塊
堆算法 heapq模塊
緩存算法 functors.lru_cache(Least Recent Used,python3)

coolections模塊提供了一些內置數據結構的擴展node

collections
Point = collections.namedtuple('Point','x','y')
p = Point(1,2)

namedtuple讓tuple屬性可讀python

de = collections.deque()
de.append(1)
de.appendleft(0)
c = collections.Counter()
c = coolections.Counter('abcab')

python dict 底層結構web

dict底層使用的哈希表
  • 爲了支持快速查找使用了哈希表做爲底層結構
  • 哈希表平均查找時間複雜度O(1)
  • Cpython解釋器使用二次探查解決哈希衝突問題
python list/tuple區別
  • 都是線性結構 支持下標訪問
  • list是可變對象,tuple保存的引用不可變
t = ([1],2,3)
t[0].append(1)
t
([1,1],2,3)
保存的引用不可變指的是你無法替換掉這個對象,可是若是對系那個自己是一個可變對象,是能夠修改這個引用指向的可變對象的
  • list沒發做爲字典的key, tuple能夠(可變對象不可hash)
什麼是LRUCache?

Least-Recently-Used 替換掉最近最少使用的對象算法

  • 緩存剔除策略,當緩存空間不夠用的時候須要一種方式剔除key
  • 常見的有LRU, LFU等
  • LRU經過使用一個循環雙端隊列不斷把最新訪問的key放到表頭實現

字典用來緩存,循環雙端鏈表用來記錄訪問順序後端

  • 利用python內置的dict + collections.OrderedDict實現
  • dict 用來看成k/v鍵值對的緩存
  • OrderedDict用來實現更新最近訪問的key
from collections import OrderedDict

class LRUCache:
  
  def __init__(self, capacity=128):
    self.od = OrderedDict()
    self.capacity = capacity
    
  def get(self, key): #每次訪問更新最新使用的key
    if key in self.od:
      val = self.od[key]
      self.od.move_to_end(key)
      return val
    else:
      return -1
    
  def put(self, key, value): # 更新k/v
    if key in self.od:
      del self.od[key]
      self.od[key] = value # 更新key 到表頭
    else:  # insert
      self.od[key] = value
      # 判斷當前容量是否已經滿了
      if len(self.od) > self.capacity:
        self.od.popitem(last=False) 
      code/lrucache.py
算法常考點

排序+查找,重中之重數組

  • 常考排序算法: 冒泡排序、快速排序、歸併排序、堆排序
  • 線性查找,二分查找等
  • 能獨立實現代碼(手寫), 可以分析時間空間複雜度

python web 後端常考數據結構緩存

  • 常見的數據結構鏈表、隊列、棧、二叉樹、堆
  • 使用內置結構實現高級數據結構,好比內置的list/deque實現棧
  • leetcode或者《劍指offer》上的常見題

常考數據結構之鏈表數據結構

鏈表有單鏈表、雙鏈表、循環雙鏈表app

  • 如何使用python 來表示鏈表結構
  • 實現鏈表常見操做,好比插入節點,反轉鏈表,合併多個鏈表等
  • Leetcode練習常見鏈表題目

數據結構之鏈表數據結構和算法

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
    pre = None
    cur = head
    while cur:
      nextnode = cur.next
      cur.next = pre
      pre = cur
      cur = nextnode
    ruture pre
數據結構之隊列

隊列(queue)是先進先出結構

  • 如何使用python實現隊列
  • 實現隊列的apend和pop操做,如何作到先作先出
  • 使用python的list或者collections.deque實現隊列
from collections import deque

class Queue:
   def __init__(self):
       self.items = deque()
        
   def append(self, val):
       retuen self.items.append(val)
      
   def pop(self):
       return self.items.popleft()
    
    def empty(self):
       return len(self.items) == 0
      
 def test_queue():
     q = Queue()
     q.append(0)
     q.append(1)
     q.append(2)
     print(q.pop())
     print(q.pop())
     print(q.pop())
  
 test_queue()()

0
1
2
常考數據結構之棧

棧(stack)是後進先出結構

  • 如何使用python實現棧?
  • 實現棧的push 和 pop 操做, 如何作到後進先出
  • 一樣能夠用python list 或者collections.deque實現棧
from collections import deque
class Stack(object):
    def __init__(self):
        self.deque = deque() # 或者用list
    
    def push(self, value):
         self.deque.append(value)
        
    def pop(self):
         return self.deque.pop()

一個常考問題: 如何用兩個棧實現隊列?

常考數據結構之字典與集合

python dict/set 底層都是哈希表

  • 哈希表的實現原理,底層其實就是一個數組
  • 根據哈希函數快速定位一個元素,平均查找,很是快
  • 不斷加入元素會引發哈希表從新開闢空間,拷貝以前元素到新數組
相關文章
相關標籤/搜索