1. 题目来源
2. 题目解析
链表题目考试遇到了,不要死磕,怎么投机怎么来。一般将值存到数组中进行操作后对链表进行重建,或者不要进行指针的操作,只进行值的交换。最后就是实际意义下对链表指针进行操作,进行指针指向的改变,补题这样做,直接麻烦到自闭…
注意:
- 本题头结点可能发生改变,则需要使用虚拟头结点
- 链表指针写法十分麻烦。尤其是当
k
和n-k
节点快相邻的时候就又产生了一大堆的指针问题需要特判。看代码注释即可。
- 时间复杂度: O ( n ) O(n) O(n)。
- 空间复杂度: O ( 1 ) O(1) O(1)
代码:
// 数组+链表重建
class Solution {
public:
ListNode* swapNodes(ListNode* head, int k) {
vector<int> a;
for (auto p = head; p; p = p->next) a.push_back(p->val);
swap(a[k - 1], a[a.size() - k]);
head = new ListNode(a[0]);
auto tail = head;
for (int i = 1; i < a.size(); i ++ )
tail = tail->next = new ListNode(a[i]);
return head;
}
};
// swap()交换值
class Solution {
public:
ListNode* swapNodes(ListNode* head, int k) {
auto dummy = new ListNode(-1);
dummy->next = head;
int n = 0;
for (auto p = dummy; p; p = p->next) n ++ ;
auto a = dummy, b = dummy;
for (int i = 0; i < k; i ++ ) a = a->next;
for (int i = 0; i < n - k; i ++ ) b = b->next;
swap(a->val, b->val);
return dummy->next;
}
};
// swap()交换 简易版
class Solution {
public:
ListNode* swapNodes(ListNode* head, int k) {
int n = 0;
for (auto p = head; p; p = p->next) n ++ ;
auto a = head, b = head;
for (int i = 0; i < k - 1; i ++ ) a = a->next;
for (int i = 0; i < n - k; i ++ ) b = b->next;
swap(a->val, b->val);
return head;
}
};
// 标准链表做法,十分麻烦,边界情况十分多
class Solution {
public:
ListNode* swapNodes(ListNode* head, int k) {
auto dummy = new ListNode(-1);
dummy->next = head;
int n = 0;
for (auto p = dummy; p; p = p->next) n ++ ;
k ++ ;
auto a = dummy; // a 是第k节点的前一个
for (int i = 0; i < k - 2; i ++ ) a = a->next;
auto b = dummy; // b 是倒数第k节点的前一个
for (int i = 0; i < n - k; i ++ ) b = b->next;
if (a == b) return dummy->next;
auto pa = a->next, qa = pa->next; // 该记的全部记录下来,便于指针改变
auto pb = b->next, qb = pb->next;
if (a->next == b) {
// 如果出现距离太近,可能交换完产生环的情况
a->next = qa, qa->next = pa;
pa->next = qb;
return dummy->next;
} else if (b->next == a) {
// 同上,这是两个特殊的边界情况
b->next = qb, qb->next = pb;
pb->next = qa;
return dummy->next;
}
pa->next = qb, b->next = pa; // 正常情况下,改变指针指向即可
pb->next = qa, a->next = pb;
return dummy->next;
}
};