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;
}
};