链表操作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;
}
posted @ 2024-12-13 16:43  yaoguyuan  阅读(3)  评论(0编辑  收藏  举报