61. 旋轉連結串列
錯誤程式碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode rotateRight(ListNode head, int k) {
ListNode dummy = new ListNode(0, head);
ListNode node = dummy;
for(int i = 0;i < k; i++) {
if (node.next != null) {
node = node.next;
} else {
node = head;
}
}
ListNode cutNode = node.next;
node.next = null;
cutNode = this.reverse(cutNode);
cutNode.next = dummy.next;
return dummy.next;
}
private ListNode reverse(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode dummy = new ListNode(0, head);
ListNode pre = dummy;
ListNode cur = head;
while (cur != null) {
ListNode nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;
}
return dummy.next;
}
}
首先理解題目有誤,以為是需要將斷點後的連結串列翻轉再接上頭節點。
另外翻轉連結串列也寫錯了。。
翻轉連結串列也不需要dummy節點,因為實際頭節點會發生變更,而不是原來的頭節點。、
以下為AI分析:
程式碼的目的是實現連結串列的右旋轉操作,但實現中存在幾個關鍵錯誤,導致程式碼無法正確完成旋轉任務。下面是錯誤的詳細分析和正確的旋轉實現方法。
錯誤分析
-
旋轉邏輯錯誤:程式碼試圖透過切割和反轉連結串列的一部分來實現旋轉,這與旋轉連結串列的正確邏輯不符。正確的旋轉操作應該是將連結串列的後部分移動到前面來,而不是反轉連結串列的一部分。
-
對
k
的處理:如果k
大於連結串列的長度,應該先對k
進行取模操作,以確保旋轉的步數不超過連結串列的長度。程式碼中沒有處理這一點。 -
反轉操作不應該出現:在旋轉連結串列的任務中,不需要反轉連結串列的任何部分。程式碼中的
reverse
方法不應該被使用。
正確的旋轉連結串列方法
下面是一個正確實現連結串列右旋轉操作的程式碼示例:
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if (head == null || head.next == null || k == 0) {
return head;
}
// 計算連結串列長度並獲取尾節點
int length = 1;
ListNode tail = head;
while (tail.next != null) {
tail = tail.next;
length++;
}
// 連線尾節點與頭節點,形成環
tail.next = head;
// 計算新的尾節點位置
k = k % length;
int stepsToNewHead = length - k;
ListNode newTail = tail;
while (stepsToNewHead-- > 0) {
newTail = newTail.next;
}
// 獲取新的頭節點,並斷開環
ListNode newHead = newTail.next;
newTail.next = null;
return newHead;
}
}
程式碼解釋
-
特殊情況處理:如果連結串列為空、只有一個節點或
k
為0,直接返回原連結串列。 -
計算連結串列長度:遍歷連結串列以計算其長度,並在此過程中獲取尾節點。
-
形成環:將尾節點的
next
指向頭節點,形成一個環。 -
計算新的頭節點和尾節點:根據
k
的值計算新的頭節點的位置。由於是右旋轉,新的頭節點實際上是從連結串列尾部向前數k
個節點的位置。 -
斷開環:在新的尾節點處斷開環,得到旋轉後的連結串列。
這種方法正確處理了連結串列的右旋轉操作,無需反轉連結串列的任何部分。