LeetCode反轉連結串列題目總結
阿新 • • 發佈:2021-08-04
核心演算法在於反轉前N個連結串列的結點,有兩種實現方式。
迭代實現方式如下:
ListNode* Reverse(ListNode *head, int n) { ListNode *pre = nullptr; ListNode *cur = head; ListNode *nxt = head; for (int i = 0; i < n; i++) { nxt = cur->next; cur->next = pre; pre = cur; cur = nxt; } head->next = cur; return pre; }
改變每個結點指標的指向,使其指向其前一個結點。
遞迴實現方式如下:
ListNode *successor = nullptr; ListNode* Reverse(ListNode *head, int n) { if (1 == n) { successor = head->next; return head; } ListNode *last = Reverse(head->next, n - 1); head->next->next = head; head->next = successor; return last; }
每次都將頭節點移動到已完成反轉的前N個結點的末端。
206. 反轉連結串列
遞迴法AC程式碼:
class Solution { public: ListNode* reverseList(ListNode* head) { if (nullptr == head) return head; if (nullptr == head->next) { return head; } ListNode*last = reverseList(head->next); head->next->next = head; head->next = nullptr; return last; } };
耗時4 ms
。
迭代法AC程式碼:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *pre = nullptr;
ListNode *cur = head;
ListNode *nxt = head;
while (nullptr != cur) {
nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
};
耗時4 ms
。
92. 反轉連結串列II
純遞迴法AC程式碼:
class Solution {
ListNode *successor = nullptr;
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
if (1 == left) {
head = Reverse(head, right - left + 1);
return head;
}
head->next = reverseBetween(head->next, left - 1, right - 1);
return head;
}
// 反轉連結串列前n個結點
ListNode* Reverse(ListNode* head, int n) {
if (1 == n) {
successor = head->next;
return head;
}
ListNode *last = Reverse(head->next, n - 1);
head->next->next = head;
head->next = successor;
return last;
}
};
耗時0 ms
。
迭代法AC程式碼:
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
ListNode *dummy = new ListNode(-1);
dummy->next = head;
ListNode *p = dummy;
for (int i = 1; i < left; i++) {
p = p->next;
}
p->next = Reverse(p->next, right - left + 1);
return dummy->next;
}
// 反轉連結串列前n個結點
ListNode* Reverse(ListNode *head, int n) {
ListNode *pre = nullptr;
ListNode *cur = head;
ListNode *nxt = head;
for (int i = 0; i < n; i++) {
nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
head->next = cur;
return pre;
}
};
耗時0 ms
。
25. K 個一組翻轉連結串列
純迭代法AC程式碼:
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode *dummy = new ListNode(-1);
dummy->next = head;
ListNode *p = dummy->next;
ListNode *q = dummy;
while (nullptr != p) {
for (int i = 0; i < k; i++) {
if (nullptr == p) return dummy->next;
p = p->next;
}
ListNode *temp = q->next;
q->next = Reverse(temp, k);
temp->next = p;
q = temp;
}
return dummy->next;
}
// 反轉連結串列前n個結點
ListNode *Reverse(ListNode *head, int n) {
ListNode *pre = nullptr;
ListNode *cur = head;
ListNode *nxt = head;
for (int i = 0 ; i < n; i++) {
nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
head->next = cur;
return pre;
}
};
耗時8 ms
。
純遞迴法AC程式碼:
class Solution {
ListNode *successor = nullptr;
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode *p = head;
for (int i = 0; i < k; i++) {
if (nullptr == p) return head;
p = p->next;
}
ListNode *last = Reverse(head, k);
head->next = reverseKGroup(p, k);
return last;
}
// 反轉連結串列前n個結點
ListNode* Reverse(ListNode *head, int n) {
if (1 == n) {
successor = head->next;
return head;
}
ListNode *last = Reverse(head->next, n - 1);
head->next->next = head;
head->next = successor;
return last;
}
};
耗時8 ms
。