単一リンクリストのヘッドノードを指定して、リンクリストを逆にして、逆リンクリストを返します。 head
例1:
入力:ヘッド= [1,2,3,4,5]
出力: [5,4,3,2,1]
例2:
入力:ヘッド= [1,2]
出力: [2,1]
例3:
入力: head = []
出力: []
ヒント:
- リンクリスト内のノードの数は、
[0, 5000]
-5000 <= Node.val <= 5000
アイデア1:
リンクリストを前から後ろにトラバースし、3つのポインターを使用して、現在のノードcur、先行ノードprev、後続ノードcurNextをポイントし、現在のノードの次をprevにポイントします。
注:curNextがない場合、cur.nextを変更した直後にcurの背後にあるノードを見つけることはできません。
中間プロセスは次のとおりです。
コード
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null) { // 空链表直接返回
return head;
}
ListNode prev = null;
ListNode cur = head;
ListNode next;
while (cur != null) {
next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
return prev; // 循环结束之后prev指向原链表的最后一个结点,也就是新链表的第一个节点
}
}
複雑さの分析
時間計算量:O(N)がリンクリストをトラバースし、Nはリンクリストの長さです
スペースの複雑さ:O(1)
アイデア2:
再帰
通過の過程でリンクリストの最後のノードに移動します。再帰的制約は、リンクリスト全体をトラバースする終了条件です。戻る過程で、次のポイントの変更が完了します。
コード:
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
}
複雑さの分析
時間計算量:O(N)、Nはリンクリストの長さであり、次の変更操作が各ノードで実行されます
スペースの複雑さ:O(N)、Nはリンクリストの長さ、再帰の複雑さは主に再帰スタックが占めるスタックスペースに依存します