代码随想录算法训练营第四天 | 24. 两两交换链表中的节点 、 19.删除链表的倒数第N个节点、面试题 02.07. 链表相交 、 142.环形链表I

代码随想录算法训练营第四天 | 24. 两两交换链表中的节点19.删除链表的倒数第N个节点面试题 02.07. 链表相交142.环形链表II


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

题目链接:24. 两两交换链表中的节点 - 力扣(LeetCode)

思路:

​ 间隔的遍历所有节点 (当前节点 cur 、下一节点 ne 、ne 的下一节点 temp)

ListNode* fun(ListNode *head){
    ListNode *q = head;
    if(NULL != head && NULL != head->next){   // 不为空链表
        q = head->next;
        ListNode *cur = head;// 当前节点
        ListNode *ne = head->next;// 下一节点 
        ListNode *temp;// 下一个“当前节点”

        while(ne != NULL){
            temp = ne->next;
            if(temp != NULL && temp->next != NULL){
                cur->next = temp->next;
            }else{
                cur->next = temp;
            }
            ne->next = cur;
            cur = temp;
            if(temp != NULL)ne = temp->next;
            else break;
        }   
    }
    return q;
}


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

题目链接:19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

思路: 使用虚拟头节点,这样就能通式化的处理链表上的每一个节点;

ListNode* removeNthFromEnd(ListNode* head, int n) {
    
    ListNode *Head = new ListNode(99);// 设置一个虚拟头节点 ,函数返回 Head->next;
    ListNode *left = Head,*right=Head;

    Head->next = head;

    ListNode *p = Head->next;
    n++;
    while(n--){
        right = right->next;
    }
    while(right != NULL){
        right = right->next;
        left = left->next;
    }
    // 此时 left 指向 带删除节点的前一个节点
    ListNode *temp = left->next;
    left->next = left->next->next;
    delete temp;
    return Head->next;
}
		

面试题 02.07. 链表相交

题目链接:面试题 02.07. 链表相交 - 力扣(LeetCode)

思路: 乍一看我想 反转列表的,看到题目要求不能改变原始结构。emm,看来反转列表不是出题者想考的。

​ 本体需要注意的是 指针相同,而不是数值相同

​ 当时看着 case1

[4,1,8,4,5]

[5,0,1,8,4,5]

预期结果

Intersected at '8’

看了看讨论区才恍然大悟。虽然值一样,但是地址不一样 所以不是从 ‘1’ 开始相交。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *ans = NULL;
        ListNode *pa = headA;
        ListNode *pb = headB;
        int lena = 0,lenb = 0;
        while(NULL != pa){
            lena++;
            pa = pa->next;
        }
        while(NULL != pb){
            lenb++;
            pb = pb->next;
        }
        int n = abs(lena-lenb);

        pa = headA;
        pb = headB;
        while(n--){
            if(lena > lenb){
                pa = pa->next;
            }else if(lenb>lena){
                pb = pb->next;
            }
        }

        while( pa != NULL && pa != pb){
            pa = pa->next;
            pb = pb->next;
        }
        if(pa!= NULL  && pa == pb) ans = pa;

        return ans;
    }
};

142.环形链表II

题目链接:142. 环形链表 II - 力扣(LeetCode)

思路:

  • ​ 利用快慢指针 来判断有无环
    • while(fast->next != NULL && fast != slow)
  • 根据数学关系 判断入环时的 节点个数。
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *slow = head;
        ListNode *fast = head;

        while(fast != NULL && fast->next != NULL){
            slow = slow->next;
            fast = fast->next->next;
            if (fast == slow)
            {
                slow = head;
                while(slow != fast){
                    slow = slow->next;
                    fast = fast->next;
                }
                return fast;
            }
        }
        return NULL;
    }
};

今日总结:

​ 链表还需要

你可能感兴趣的:(代码随想录训练,链表)