python为什么没有指针_Python 没有指针,如何解算法题?
👆“Python貓” ,一個值得加星標的公眾號
花下貓語:
今天一大早,讀者群里又討論了 Python 的“指針”問題。之前在公眾號里發布過櫻雨樓小姐姐的《對比 C++ 和 Python,談談指針與引用》,它從概念上有比較清晰的分析。恰好今天還看到青南同學剛發布的一篇文章,它從實用的層面介紹了怎么用 Python 解“指針”類的題目,正好分享一下~
劇照 | 《如懿傳》
原標題:《舉一反三:三種問題,兩個指針,一種方法》
在我們做算法題的時候,如果大家多總結解題方法,就會發現很多題目的解題方法實際上是完全一樣的。今天我們就來看三道鏈表相關的題目。可以使用同一種方法來解決。
雖然題目中用到了指針,但我們知道,Python 是沒有指針的,所以在 Python 里面,這里實際上指的是引用。不過由于“指針”這個詞更加形象,所以下文我們還是會用指針來表示對一個對象的應用。
先來看我們將要解決的三道題目:
題目1:只掃描一次鏈表,O(1)空間復雜度,返回鏈表倒數第 k 個節點。
題目2:只掃描一次鏈表,O(1)空間復雜度,返回鏈表中間的節點。
題目3:空間復雜度(1),查詢鏈表是否有環。
其中前兩道題要求只能掃描鏈表一次。但是大家可能會有疑問,例如對于第2題,都不知道鏈表一共有多少個節點,怎么可能知道中間的節點是哪個?但如果提前把鏈表掃描一遍,知道一共有多少個節點了,又不能再次掃描鏈表,那么就必須把每個節點和序號都存下來,這樣空間復雜度就不可能是 O(1)了。
我們先來看看第2題,找到鏈表中間的節點。
從下圖的兩個鏈表可以看到:
鏈表有 n 個節點,如果 n 為奇數,那么中間的節點在第 (n + 1) / 2個節點。如果 n 為偶數,那么中間的節點在第n / 2個節點。
這個信息怎么使用呢?我們看下面一個表格:
既然如此,如果我們在鏈表里面有兩個指針(引用),其中一個每次移動2個節點,另一個每次移動一個節點。這樣當快的指針移動到了末尾,慢的指針剛剛好指向中間的節點。
用代碼來表示:
def find_mid(node):
if not node:
return None
if not node.next:
return node
fast = slow = node
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
return slow
返回的 slow 就是最中間的節點。
再來看第3道題。跟第二題一樣,也是一快一慢兩個指針,如果鏈表有環,那么快的指針會繞到慢的指針的后面,然后追上來。只要看快的指針是否跟慢的指針重合,就知道是否有環了:
def find_cycle(node):
if not node:
return False
slow = fast = node
while fast:
fast = fast.next
if not fast: # 快的指針到了鏈表末尾,說明沒有環
return False
if fast is slow: # 快的指針追上了慢的指針,說明有環
return True
fast = fast.next
if fast is slow:
return True
slow = slow.next
return False
再來看第一題。跟第二題實際上也是一樣的。只不過,這次兩個指針是移動速度是一樣的。但是,一種一個指針先移動 k 個節點,然后兩個指針再開始同時移動。這樣兩個指針中間始終會間隔 k 個節點。這樣一來,當先走的指針到了None,后走的指針剛剛好走到倒數第 k 個節點。
不過,在解決這道題的時候,需要考慮,k 如果大于鏈表長度的時候,應該要返回錯誤信息。對應的代碼如下:
def find_reverse_k(node, k):
if not node or k == 0:
return None
front = behind = node
window = 0
while front:
window += 1
front = front.next
if window == k:
break
else: # while ... else 語法,如果循環正常結束,就會進入 else
raise Exception('k 比鏈表長度還長!')
while front:
front = front.next
behind = behind.next
return behind
如果大家觀察上面三個問題的解決代碼,會發現他們都是使用了兩個指針,通過兩個指針之間的節點差來解決問題的。
總結
以上是生活随笔為你收集整理的python为什么没有指针_Python 没有指针,如何解算法题?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: word中怎样单独删除某一页的页码
- 下一篇: python3多线程编程_Python