目录
1 19. 删除链表的倒数第 N 个节点
2 24. 两两交换链表中的节点
3 25. K 个一组翻转链表
4 138. 随机链表的复制
菜鸟做题第三周,语言是 C++
1 19. 删除链表的倒数第 N 个节点
到底是节点还是结点。。。
解题思路:
- 设置双指针 left 和 right
- 先让 right 右移 n 格
- 再让 left 和 right 一起右移直至 right 指向 nullptr
- left 将恰好处于被删除节点的前一个节点
思路说明图:
这个虚拟节点(dummy node)的设置非常巧妙,完美处理了被删除节点是头节点的情况。
class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode * dummy = new ListNode(0, head);ListNode * left = dummy, * right = head;for (int i = 0; i < n; ++i) {right = right->next;}while (right) {left = left->next;right = right->next;}left->next = left->next->next;return dummy->next;}
};
虽然不设置虚拟节点(dummy node)也能做,但是写 if 语句的模样真的很狼狈。
2 24. 两两交换链表中的节点
思路很简单,一组一组地交换即可,关键在于保存需要再次使用到的节点指针。
public:ListNode* swapPairs(ListNode* head) {ListNode * dummy = new ListNode(0, head);ListNode * prev = dummy, * post = nullptr;ListNode * left = head, * right = head ? head->next : nullptr;while (left && right) {post = right->next;right->next = left;left->next = post;prev->next = right;prev = left;left = post ? post : nullptr;right = post ? post->next : nullptr;}return dummy->next;}
};
说明:以下是为了防止指针越界而进行的判断
left = post ? post : nullptr;
right = post ? post->next : nullptr;
3 25. K 个一组翻转链表
是上一题的升级版。
解题思路:
- 设置 prev、left、right、temp、next 指针
- prev 用于保存上一组的尾巴
- left 用于保存当前组的头部
- right 和 temp 一起右移,对每一个指针进行反向
是不是看起来很烦,但确实可能要使用到很多指针。
我加了一个函数来判断剩余部分还能不能构成 K 个一组:
bool isEnough(ListNode * p, int k) {int count = 0;while (p && count < k) {p = p->next;++count;}return count == k;
}
其实思路也不难,就是容易转晕:
class Solution {
public:bool isEnough(ListNode * p, int k) {int count = 0;while (p && count < k) {p = p->next;++count;}return count == k;}ListNode* reverseKGroup(ListNode* head, int k) {ListNode * dummy = new ListNode(0, head);ListNode * left = head, * right = head->next;ListNode * prev = dummy;while (isEnough(left, k)) {int count = 1;ListNode * temp = left;while (count < k) {++count;ListNode * next = right->next;right->next = temp;temp = right;right = next;}prev->next = temp;prev = left;left->next = right;left = right;right = left ? left->next : nullptr;}return dummy->next;}
};
4 138. 随机链表的复制
这道题用递归真是太神奇了,可惜我不会。。。
class Solution {
public:unordered_map<Node *, Node *> cachedNode;Node* copyRandomList(Node* head) {if (head == nullptr) return nullptr;if (!cachedNode.count(head)) {Node * headNew = new Node(head->val);cachedNode[head] = headNew;headNew->next = copyRandomList(head->next);headNew->random = copyRandomList(head->random);}return cachedNode[head];}
};