遞迴反轉鍊錶 如何拆解複雜問題

2021-10-13 12:52:34 字數 2944 閱讀 4867

對於單鏈表講,單鏈表中的結點不一定儲存在相鄰位置,乙個結點儲存兩個資訊,一是該節點的值,二是指向下乙個結點的位置資訊。

// 單鏈表節點的結構

public

class

listnode

}

本文的主要目的是以單鏈表出發,遞迴實現反轉單鏈表——>反轉鍊錶前n個結點——>反轉鍊錶的一部分

這個演算法可能很多讀者都聽說過,這裡詳細介紹一下,先直接看實現**:

listnode reverse

(listnode head)

下面來詳細解釋一下這段**。

首先(大體出現鍊錶反轉的結果):

對於遞迴演算法,最重要的就是明確遞迴函式的定義。具體來說,我們的reverse函式定義是這樣的:

輸入乙個節點head,將「以head為起點」的鍊錶反轉,並返回反轉之後的頭結點。

明白了函式的定義,再來看這個問題。比如說我們想反轉這個鍊錶:

那麼輸入reverse(head)後,會在這裡進行遞迴:

listnode last = reverse(head.next);
不要跳進遞迴(你的腦袋能壓幾個棧呀?),而是要根據剛才的函式定義,來弄清楚這段**會產生什麼結果:

按照定義,這個reverse(head.next)執行完成後,整個鍊錶應該變成了這樣:

並且根據函式定義,reverse函式會返回反轉之後的頭結點,我們用變數last接收了。

然後(指標進行修正上下結點):

現在再來看下面的**:

head.next.next = head; //修正上結點——將head的位址賦予元素2的位址(即鍊錶2後面指向1)

接下來進行的操作:

head.next = null; // 修正下結點

最後(遞迴結束邊界base case):

if (head.next == null) return head;
**小小總結下

大體可以分為以下三步驟:

對於遞迴問題,我們一定要知道遞迴的定義(遞迴後長怎麼樣的?)

對於遞迴後的鍊錶修改上下結點的(位置)指向

明白遞迴的終止條件(basecase)——結點指向下乙個位置為null

理解了這兩點後,我們就可以進一步深入了,接下來的問題其實都是在這個演算法上的擴充套件。

首先看下大概的過程:

**實現如下:

listnode tem = null;

// 後驅結點(用來修改——反轉後中 返回結點的指向!)

listnode reserven

(listnode head,

int n)

// 以 head.next 為起點,需要反轉前 n - 1 個節點

listnode last =

reseven

(head.next, n-1)

; head.next.next = head;

// 讓反轉之後的 head 節點和後面的節點連起來

head.next = tem;

return last;

}

小小總結下反轉鍊錶前n個結點對比第乙個反轉鍊錶,大體的思路差不多,都是

定義遞迴方程(明白遞迴反戰後是長怎麼樣的?)

對於遞迴後的鍊錶修改上下結點的(位置)指向

明白遞迴的終止條件(basecase)——結點指向下乙個位置為null

但是相比較第乙個,這裡重點關注結束條件——n,和返回結點的指向(第乙個是指向null,這個是指向第n個結點的下乙個

問題:給乙個索引區間[m,n](索引從 1 開始),僅僅反轉區間中的鍊錶元素。

listnode reversebetween

(listnode head,

int m,

int n)

// 前僅到反轉的起點觸發 base case

head.next =

reversebetween

(head.next, m-

1, n-1)

;return head;

}

核心關注點是:邊界狀態呼叫鍊錶中的前n個結點

遞迴強調三步驟:

定義遞迴方程(遞迴後長怎麼樣的?)

遞迴直接呼叫返回(腦子別壓棧!)

明白遞迴終止條件(basecase)

參考:

分析讓複雜問題簡單 複雜鍊錶的複製

輸入乙個複雜鍊錶 每個節點中有節點值,以及兩個指標,乙個指向下乙個節點,另乙個特殊指標指向任意乙個節點 返回結果為複製後複雜鍊錶的head。注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空 思路 1,如果鍊錶為空鍊錶,則返回本身即可。2,如果鍊錶非空的情況 如果沒有特殊指標,則只...

(複雜問題分步驟)劍指 複雜鍊錶的複製

輸入乙個複雜鍊錶 每個節點中有節點值,以及兩個指標,乙個指向下乙個節點,另乙個特殊指標指向任意乙個節點 返回結果為複製後複雜鍊錶的head。注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空 占用記憶體 9400k public class randomlistnode publi...

35 複雜鍊錶的複製( 分解讓複雜問題簡單)

題目描述 輸入乙個複雜鍊錶 每個節點中有節點值,以及兩個指標,乙個指向下乙個節點,另乙個特殊指標指向任意乙個節點 返回結果為複製後複雜鍊錶的head。注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空 測試用例 功能測試 節點中的random指向自身 兩個節點的random形成環狀...