Day4 链表专项 — 交换、双指针、交点、环

LeetCode 24. 两两交换链表中的节点

解题思路:明确交换步骤,记录必要的临时节点

ListNode* swapPairs(ListNode* head) {
    ListNode* dummy_head = new ListNode(0);
    dummy_head->next = head;
    ListNode* cur = dummy_head;
    while(cur->next && cur->next->next) {
        // 临时记录
        ListNode* temp1 = cur->next;
        ListNode* temp2 = cur->next->next->next;
        
        // 交换步骤
        cur->next = cur->next->next;
        cur->next->next = temp1;
        temp1->next = temp2;

        cur = cur->next->next;
    }
    return dummy_head->next;
}

LeetCode 19. 删除链表的倒数第N个节点

解题思路:

  • 双指针,fast在n的步长基础上再加1,删除slow指向的下一个节点,无需记录pre
  • 虚拟头结点,使第一个节点的操作与其他节点相同
ListNode* removeNthFromEnd(ListNode* head, int n) {
    // 虚拟头结点用于统一第一个节点与其他节点的操作
    ListNode* dummpy_head = new ListNode(0);
    dummpy_head->next = head;
    // fast先走n步长
    ListNode* fast = dummpy_head;
    while(n-- > 0) {
        fast = fast->next;
        if (!fast) {
            return head;
        }
    }
    // fast多走一步,这样后续可以直接删除slow指针指向的下一个节点
    fast = fast->next;
    ListNode* slow = dummpy_head;
    while(fast) {
        fast = fast->next;
        slow = slow->next;
    }
    // 删除操作
    ListNode* temp = slow->next;
    slow->next = slow->next->next;
    delete temp;
    return dummpy_head->next;
}

LeetCode 160. 链表相交

解题思路:计算两链表长度差值,长链表先走差值,后依次相比

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    // 计算两链表长度
    ListNode* calculate_a = headA;
    int len_a = 0;
    while(calculate_a) {
        len_a++;
        calculate_a = calculate_a->next;
    }

    ListNode* calculate_b = headB;
    int len_b = 0;
    while(calculate_b) {
        len_b++;
        calculate_b = calculate_b->next;
    }

    // 归类长、短链表
    ListNode* long_list_head = nullptr;
    ListNode* short_list_head = nullptr;
    int diff = 0;
    if (len_a > len_b) {
        long_list_head = headA;
        short_list_head = headB;
        diff = len_a - len_b;
    } else {
        long_list_head = headB;
        short_list_head = headA;
        diff = len_b - len_a;
    }

    // 长链表先走
    while (diff-- > 0) {
        long_list_head = long_list_head->next;
    }  

    // 找相交节点
    while(long_list_head) {
        if (long_list_head == short_list_head) return long_list_head;
        long_list_head = long_list_head->next;
        short_list_head = short_list_head->next;
    }

    return NULL;
}

LeetCode 142. 环形链表

解题思路:

  • 判断是否有环可以通过慢指针能否追上快指针判断
  • 在头结点与快慢指针相遇的节点出重新出发一个指针,再次相遇时即为环的入口
ListNode *detectCycle(ListNode *head) {
    ListNode* fast = head;
    ListNode* slow = head;
    while(slow && fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
        // 如果有环
        if (slow == fast) {
            ListNode* index1= head;
            ListNode* index2= fast;
            // 头结点与相遇节点重新出发指针
            // 两指针相遇时则为环的入口
            while (index1 != index2) {
                index1 = index1->next;
                index2 = index2->next;
            }
            return index1;
        }
    }
    return NULL;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值