链表操作2
[Algo] 链表操作2
1. 两个链表的交点
ListNode *intersectionNode(ListNode *head1, ListNode *head2)
{
if (head1 == nullptr || head2 == nullptr) return nullptr;
ListNode *cur1 = head1, *cur2 = head2;
int len1 = 1, len2 = 1;
while (cur1->next != nullptr)
{
cur1 = cur1->next;
len1++;
}
while (cur2->next != nullptr)
{
cur2 = cur2->next;
len2++;
}
if (cur1 != cur2) return nullptr;
cur1 = len1 >= len2 ? head1 : head2;
cur2 = len1 >= len2 ? head2 : head1;
for (int i = 0; i < abs(len1 - len2); i++) cur1 = cur1->next;
while (cur1 != cur2)
{
cur1 = cur1->next;
cur2 = cur2->next;
}
return cur1;
}
2. 链表按k个为一组逆序
// (1) 查找当前组的末尾节点
ListNode *teamEnd(ListNode *start, int k)
{
if (start == nullptr) return nullptr;
for (int i = 0; i < k - 1; i++)
{
if (start->next != nullptr) start = start->next;
else return nullptr;
}
return start;
}
// (2) 链表局部逆序
void teamReverse(ListNode *start, ListNode *end)
{
ListNode *cur = start->next, *pre = start, *post;
start->next = end->next;
while (pre != end)
{
post = cur->next;
cur->next = pre;
pre = cur;
cur = post;
}
}
// 2. 链表按组逆序
ListNode *reverseByGroup(ListNode *head, int k)
{
ListNode *firstEnd = teamEnd(head, k);
if (firstEnd == nullptr) return head;
teamReverse(head, firstEnd);
ListNode *lastStart = head;
ListNode *curStart = lastStart->next;
ListNode *curEnd = teamEnd(curStart, k);
while (curEnd != nullptr)
{
teamReverse(curStart, curEnd);
lastStart->next = curEnd;
lastStart = curStart;
curStart = curStart->next;
curEnd = teamEnd(curStart, k);
}
return firstEnd;
}
3. 拷贝含有随机指针的链表
节点定义:
struct RListNode {
int val;
RListNode *next;
RListNode *rand;
RListNode(int x) : val(x), next(nullptr), rand(nullptr) {}
};
RListNode *copy(RListNode *head)
{
if (head == nullptr) return nullptr;
// 将新节点插入到老节点后面
RListNode *cur = head;
while (cur != nullptr)
{
RListNode *post = cur->next;
cur->next = new RListNode(cur->val);
cur->next->next = post;
cur = post;
}
// 赋值rand指针
cur = head;
RListNode *cur_copy = cur->next;
while (cur != nullptr)
{
cur_copy->rand = cur->rand == nullptr ? nullptr : cur->rand->next; // *
cur = cur->next->next;
if (cur_copy->next == nullptr) break;
cur_copy = cur_copy->next->next;
}
// 将新老链表分离
cur = head;
cur_copy = cur->next;
RListNode *ret = cur_copy;
while (cur != nullptr)
{
RListNode *post = cur_copy->next;
cur->next = post;
if (post == nullptr)
{
cur_copy->next = nullptr;
break;
}
cur_copy->next = post->next;
cur = post;
cur_copy = post->next;
}
return ret;
}
4. 判断回文链表
bool isPalindrome(ListNode *head)
{
// 快慢指针————快指针一次跳2下,慢指针一次跳1下;当快指针无法继续时,慢指针指向链表重点。
ListNode *slow = head, *fast = head;
while (fast->next != nullptr && fast->next->next != nullptr)
{
fast = fast->next->next;
slow = slow->next;
}
if (fast->next != nullptr) fast = fast->next;
ListNode *fast_tmp = fast;
teamReverse(slow, fast);
while (head != nullptr)
{
if (head->val != fast->val) break;
head = head->next;
fast = fast->next;
}
teamReverse(fast_tmp, slow);
return head == nullptr;
}