简单的链表指针操作题,注意穿针引线的时候别打结了。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
// 使用一个 dummy 节点来简化操作
// 不用额外处理头部节点,把头部节点也当成链表中间的一个节点处理即可
ListNode* dummy = new ListNode(0, head);
ListNode* prev = dummy;
ListNode* cur = head;
// 存在一对节点的时候才进行两两交换
while (cur != nullptr && cur->next != nullptr) {
ListNode* first = cur;
ListNode* second = cur->next;
first->next = second->next;
second->next = first;
prev->next = second;
prev = first;
cur = first->next;
}
return dummy->next;
}
};
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var swapPairs = function (head) {
const dummy = new ListNode(null, head);
let prev = dummy;
let cur = prev.next;
while (cur && cur.next) {
// 按照上图,指针更换顺序是这样子的
// prev.next = cur.next
// cur.next = prev.next.next
// prev.next.next = cur
// 也可以先用一个指针把下一个节点存起来
const next = cur.next;
cur.next = next.next;
next.next = cur;
prev.next = next;
prev = cur;
cur = cur.next;
}
return dummy.next;
};
用递归来解决这个问题时,我们只需要考虑这几个问题:
小问题
当前递归函数需要解决什么问题?将前后的情况都当作黑匣子,我们只需要关注当前的递归函数即可,答案显然是将两个节点进行交换
小问题之间的关系
我们将链表进行两两分组,在每个递归函数中只处理一组节点,那么各个递归函数之间的关系是什么?答案也是显而易见的,需要将各组节点重新连接。再具体点就是,下一层递归函数需要返回什么数据给当前函数,而当前递归函数需要什么数据给上一层递归函数,这两个其实是一个问题。就这道问题而已,需要返回的是交换后的第一个节点。
递归出口