今天來看一道有意思的鏈表算法題目。python
給到一個單向鏈表,要求找出該鏈表中倒數第 k >個節點,要求只能遍歷一次鏈表,且空間複雜度爲 O(1)。算法
思路1:若是能從鏈表尾部開始遍歷,那隻需倒序遍歷 k 個節點便是要找出的節點,可是因爲是單鏈表,只能從頭結點開始遍歷。數組
思路2:先遍歷一遍該單鏈表,獲取鏈表的總節點數 n,那麼第 n-k+1 這個節點就是倒數第 k 個節點。因此第二次再遍歷到第 n-k+1 這個節點便可,可是題目要求只能遍歷一遍鏈表。spa
思路3:經過遍歷該鏈表把節點都存入到一個數組中,而後再經過數組下標可直接獲取到倒數第 k 個節點,可是這樣會須要額外的存儲空間,空間複雜度爲 O(n)。指針
上面這三種常規思路其實都是不符合題目要求的,那就只能想其餘辦法了。code
咱們知道,鏈表的節點之間都是經過指針來鏈接的,咱們先額外定義兩個空指針,分別叫前指針和後指針。cdn
先讓前指針指向鏈表的頭指針並開始遍歷,一直遍歷到第 k-1 個節點,在這期間,後指針原地保持不動。blog
當前指針遍歷到第 k 個節點時,後指針也指向鏈表頭指針並開始遍歷,在這以後,前指針每日後遍歷一個節點,後指針也日後遍歷一個節點。utf-8
這樣先後兩指針的距離始終都保持爲 k-1,當前指針遍歷到鏈表的最後一個節點時,後指針恰好也就到了倒數第 k 個節點了。it
若是還沒想明白的話,看下面的圖應該就很好理解了。p1 表明前指針,p2 表明後指針,該鏈表一共有 6 個節點,要求的是倒數第 3 個節點。
固然這只是題目的解決思路,實際用代碼來實現這個算法,還有一些須要特別注意的地方。
好比頭指針不能爲空,k 不能等於 0,k 不能大於鏈表的總節點數。這些都是須要咱們在代碼中考慮到的狀況,下面附上一份用 python 實現該算法的代碼。
# -*- coding:utf-8 -*-
#鏈表節點的定義
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindKthToTail(self, head, k):
#若是頭指針爲空或k爲0 直接返回none
if head == None:
return None
if k == 0:
return None
pAhead = pBehind = head
# 快指針先走k步
for i in range(k):
#若是k大於鏈表長度,返回空
if pAhead == None:
return None
#繼續日後遍歷
pAhead = pAhead.next
#快慢指針同時日後遍歷
while pAhead != None:
pAhead = pAhead.next
pBehind = pBehind.next
return pBehind
複製代碼
有問題歡迎留言交流,如文章對你有幫助,就點個贊哈,感謝支持。