leetcode:翻转链表相关
总结一下leetcode上翻转链表的一些题目。
首先最基本的翻转链表,有迭代和递归两种方法。
class Solution {//迭代
public:
ListNode* reverseList(ListNode* head) {
if (!head || !head->next)
return head;
ListNode* pre = nullptr;
ListNode* nextNode = nullptr;
auto now = head;
while (now) {
nextNode = now->next;
now->next = pre;
pre = now;
now = nextNode;
}
return pre;
}
};
class Solution {//递归
public:
ListNode* reverseList(ListNode* head) {
return reverseHelper(head, nullptr);
}
private:
ListNode* reverseHelper(ListNode* now, ListNode* pre) {
if (!now)
return pre;
auto nextNode = now->next;
now->next = pre;
return reverseHelper(nextNode, now);
}
};
注意的是,递归更加简洁一些,它是我们做后面翻转链表题目的基础。
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
auto dummyNode = new ListNode(0);
dummyNode->next = head;
int cnt = 0;
auto p = dummyNode;
while (++cnt < m)
p = p->next;
auto preM = p;
p = p->next;
while (++cnt <= n)
p = p->next;
auto nNext = p->next;
p->next = nullptr;
preM->next = helper(preM->next, nNext);
return dummyNode->next;
}
private:
ListNode* helper(ListNode* now, ListNode* pre) {
if (!now)
return pre;
auto nextNode = now->next;
now->next = pre;
return helper(nextNode, now);
}
};
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if (!head)
return head;
int cnt = 0;
auto p = head;
while (++cnt < k && p)
p = p->next;
if (!p)
return head;
auto nextNode = p->next;
p->next = nullptr;
return doReverse(head, reverseKGroup(nextNode, k));
}
private:
ListNode* doReverse(ListNode* now, ListNode* pre) {
if (!now)
return pre;
auto nextNode = now->next;
now->next = pre;
return doReverse(nextNode, now);
}
};
这一题是最有意思的,它以上一题为基础进行了变形,有了两个递归,一个是整体的递归,还有一个是真正做翻转的局部的递归,分清两个递归是其中的难点。