題目描述
反轉一個單鏈表。
示例:
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
進階:
你可以迭代或遞歸地反轉鏈表。你能否用兩種方法解決這道題?
思路
反轉鏈表是面試中常考的題目,但是我在看到這道題的時候還是確確實實倒騰了半天,越想越亂,然後無奈用了其他數據結構實現。
有的時候不妨可以先試試遞歸的解法,將複雜的問題化簡爲一個相同的小問題。反而能讓你縷清思路。
注,像原地翻轉這樣的題目,一般是需要兩個指針變量來實現。
我將思路大致畫了一個草圖,供大家參考。
本來是想稍作解釋的,但是還是覺得遞歸的代碼更簡潔,那就直接上代碼吧
解法一
public ListNode reverseList(ListNode head) {
if (head == null) {
return head;
}
ListNode dummy = null;
return reverseList(head,dummy);
}
public ListNode reverseList(ListNode currentNode,ListNode lastNode){
//遞歸到底的情況
if(currentNode.next == null){
currentNode.next = lastNode;
return currentNode;
}
//正常情況
//解釋一下,每個步驟分爲三個結點,分別爲“上一個結點”,“當前結點”和“下一個結點”
ListNode nextNode = currentNode.next;//備份下一個結點
currentNode.next = lastNode;//將當前結點的指針指向上一個結點
lastNode = currentNode;//上一個結點的指針指向當前結點
currentNode = nextNode;//當前結點的指針指向下一個結點
return reverseList(currentNode,lastNode);
}
解法二
用迭代的方法描述這個步驟爲:
public ListNode reverseList(ListNode head) {
if (head == null) {
return head;
}
ListNode pre = null;
while (head != null) {
ListNode newCurrent = head.next;
head.next = pre;
pre = head;
head = newCurrent;
}
return pre;
}
總結
- 翻轉的題目一般需要兩個指針協助完成,看到“翻轉”想到“雙指針”。
- 遞歸寫法的小技巧。分爲“遞歸到底的情況”和“正常情況”。將化繁爲單一的遞歸問題再次拆分。