2 つのリンクされたリストの最初の共通ノード
ダブルポインタ
2 つのポインター p と q を使用して、2 つのリンク リスト head1 と head2 のヘッド ノードをそれぞれ指し、同時にノードごとにトラバースします。p がリンク リスト head1 の末尾に到達すると、ヘッド ノードに再配置されます。リンクされたリストの head2; q が到着すると、リンクされたリストの head2 の最後で、リンクされたリストの head1 のヘッド ノードに再配置されます。このようにして、p と q が出会うとき、指されるノードが最初の共通ノードになります。head1 から共通ノードまでの長さを a、head2 から共通ノードまでの長さを b とすると、a+b=b+a となり、スプライス後、head1 と 2 から共通ノードまでの長さは等しくなります。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode *p=pHead1, *q=pHead2;
while(p!=q){
if(p==NULL) p=pHead2;
else p=p->next;
if(q==NULL) q=pHead1;
else q=q->next;
}
return p;
}
};
スタック:リンクされたリストのノードをスタックにロードし、最上位のノードを比較してから、スタックを走査して共通のノードを見つけます。
リンク リストの長さの差: 2 つのリンク リスト headA と headB をそれぞれ走査します。ポインターが同じ場合は直接戻ります。そうでない場合は、リンク リストの長さの差を計算します。変数 step を使用して長いリンク リストの長さを計算します。短いリンク リストと比較して、次に、長いリンク リストを最初に実行し、次にリンク リスト headA と headB を同期して移動させて共通のノードを見つけます。
リンクリスト追加(2)
2 つのリンクされたリストを反転して追加します
反転後に先頭から加算し、整数変数を使用してキャリー値を記録し、ヘッド補間を使用して結果を保存し、最後に結果を反転します
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
/**
*
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
ListNode* addInList(ListNode* head1, ListNode* head2) {
// write code here
head1=reverse(head1);
head2=reverse(head2);
ListNode *dummy = new ListNode(0);
ListNode *cur=dummy;
int jw=0;//进位
while (head1 || head2 || jw) {
int sum = jw;
if(head1){
sum += head1->val;
head1=head1->next;
}
if(head2){
sum += head2->val;
head2=head2->next;
}
jw = sum /10;
sum %= 10;
cur->next=new ListNode(sum);
cur=cur->next;
}
ListNode *res=reverse(dummy->next);//结果翻转
return res;
}
ListNode* reverse(ListNode *head){
ListNode *pre=NULL, *cur=head;
while(cur!=NULL){
ListNode *next=cur->next;
cur->next=pre;
pre=cur,cur=next;
}
return pre;
}
};
単一リンクリストのソート
マージソート
順序なしリストを左右 2 つに分割し、それぞれを順序付きリストとみなすことができるように再帰的に分解し、順序付きリストをペアとしてマージします
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
#include <algorithm>
class Solution {
public:
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
ListNode* sortInList(ListNode* head) {
// 归并排序
if (!head || !head->next) return head;
ListNode *slow = head, *fast = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
ListNode *mid = slow->next;//注意1
slow->next = nullptr;
ListNode *left = sortInList(head);
ListNode *right = sortInList(mid);
return merge(left, right);
}
ListNode *merge(ListNode* h1, ListNode* h2){
ListNode dummy(0),*p = &dummy;
while(h1 && h2){
if(h1->val < h2->val){
p->next=h1;
h1=h1->next;
}else{
p->next=h2;
h2=h2->next;
}
p=p->next;//注意2
}
if(h1) p->next=h1;
if(h2) p->next=h2;
return dummy.next;
}
};
クイックソート
ベンチマークを見つけます: 次のノードを走査します: 小さいノードを左側に配置し、大きいノードを右側に配置します。次に、左側 + ベンチマーク + 右をマージします。
// 快速排序函数
ListNode* quickSortList(ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
// 选择一个基准元素
ListNode *pivot = head;
head = head->next;
pivot->next = NULL;
// 将链表分成两个部分
ListNode *left = NULL, *right = NULL;
while (head != NULL) {
ListNode *next = head->next;
if (head->val < pivot->val) {
head->next = left;
left = head;
} else {
head->next = right;
right = head;
}
head = next;
}
// 递归地对左右两个部分进行排序
left = quickSortList(left);
right = quickSortList(right);
// 将左右两个部分和基准元素拼接起来
if (left == NULL) {
pivot->next = right;
return pivot;
} else {
ListNode *tail = left;
while (tail->next != NULL) {
tail = tail->next;
}
tail->next = pivot;
pivot->next = right;
return left;
}
}