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

题目:24.两两交换链表中的结点

文章链接:代码随想录

视频链接:LeetCode:24.两两交换链表中的节点

题目链接:力扣题目链接

解法1:

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        # head->1->2->3->NULL
        ListNode* dummphead = new ListNode();
        dummphead->next = head;
        # dhead->head->1->2->3->NULL
        ListNode* cur = dummphead;
        # dhead(cur)->head->1->2->3->NULL
        ListNode* temp = new ListNode();
        ListNode* temp1 = new ListNode();
        while(cur->next != NULL && cur->next->next != NULL) 
        //必须是cur->next != NULL,不然先判断后面那个就不会判断前面那个了
        {
           temp = cur->next;                 # temp = head
           temp1 = cur->next->next->next;    # temp1 = 2
           //一开始的cur->next->next还是head,赋值后就改变了
           cur->next = cur->next->next;      # dummphead(cur)->1  
           cur->next->next = temp;           # dummphead(cur)->1->head
           cur->next->next->next = temp1;    # dummphead(cur)->1->head->2
           cur = cur->next->next;            # dummphead->1->head(cur)->2
        }
        return dummphead->next;
    }
};

题目:19.删除链表中的倒数第N个结点

 文章链接:代码随想录

视频链接:LeetCode:19.删除链表倒数第N个节点

题目链接:力扣题目链接

解法1:暴力解法

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
       int size = 0 ;  //记录链表长度
       // 先遍历链表有多少个节点
       ListNode* dummphead = new ListNode();
       dummphead->next = head;
       ListNode* cur = head;
       while(cur->next != NULL)
       {
            cur = cur->next;
            size++;
       }
       cur = dummphead->next; //重置链表头
       while(size > n )  // 循环至第N个节点
       {
         cur = cur->next;
         size--;
       }
       # head->1->...->N-1(cur)->N->N+1->...
       ListNode* temp = cur->next;   # temp = N
       cur->next = temp->next;       # head->1->...->N-1(cur)->N+1->...
       delete temp; // 释放内存
       return dummphead->next;
    }
};

解法2:双指针

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
       # head->1->2->3->4->NULL
       ListNode* dummyhead = new ListNode();
       dummyhead->next = head;
       # dhead->head->1->2->3->NULL
       ListNode* fast = dummyhead;
       ListNode* slow = dummyhead;
       # dhead(fast)(slow)->head->1->2->3->4->NULL
       // 让快指针先走
       while(n-- && fast->next != NULL)  // 如果先走的步数没走完,或者快指针没走到null
       {
            fast = fast->next;
       }
       # dhead(slow)->head->1(fast)->2->3->4->NULL  要删除 2  
       // fast = fast->next; // fast再提前走一步,因为需要让slow指向删除节点的上一个节点
       # dhead(slow)->head->1->2(fast)->3->4->NULL
       // 当先走的步数走完了,则快慢指针一起走
       while(fast->next != NULL)  // 这里指的是 fast
       {
            fast = fast->next;
            slow = slow->next;
            # dhead->head(slow)->1->2->3(fast)->4->NULL
       }
       # dhead->head->1(slow)->2->3->4(fast)->NULL
       //当快指针走到头后,进行一个删除
       ListNode* temp = slow->next;   # temp = 2
       slow->next = temp->next;       # dhead->head->1(slow)->3->4(fast)->NULL   
       delete temp; //释放内存
       return dummyhead->next;
    }
};

题目:面试题 02.07. 链表相交

 文章链接:代码随想录

题目链接:力扣题目链接

解法1:

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        // 
        ListNode* curA = headA;
        ListNode* curB = headB;
         int lenA = 0 , lenB= 0; // 用于计数链表的长度
        // 获取每个链表的长度
        while(curA != NULL)
        {
            lenA++;
            curA = curA->next;
        }
        while(curB != NULL)
        {
            lenB++;
            curB = curB->next;
        }
        // 遍历完重新赋值回去
        curA = headA;
        curB = headB;
        // 固定最长的链表为A
        if(lenB > lenA)
        {
            swap(lenA, lenB);
            swap(curA, curB);  // 交换
        }
        // 链表相交是后面的指针相同,不是数相同,所以长的那个前面不可能等于短的
        int gap = lenA - lenB;
        // 让长的那个链表都移动到同一为止
        while(gap--)
        {
           curA = curA->next;

        }
        //
        while(curA != NULL) //两个链表在同一起跑线了,相同则返回
        {
           if(curA == curB){
               return curA;
           }
           curA = curA->next;
           curB = curB->next;
        }
        return NULL;
    }
};

题目:142.环形链表II

 文章链接:代码随想录

视频链接:LeetCode:

题目链接:力扣题目链接

解法1:

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        // 定义快慢指针
        ListNode* fast = head;
        ListNode* slow = head;
        // 判断链表为直线则退出条件
        while(fast != NULL && fast->next != NULL) // 因为快指针是要移动两格的,所以要判断中间是否为空
        // fast->next->next 是可以为NULL
        {
            // 移动
            fast = fast->next->next;
            slow = slow->next;
            if(fast == slow)
            {
                ListNode* cur = head;
                while(fast != cur)
                {
                   fast = fast->next;
                   cur = cur->next; 
                }
                return cur;
            }
        }
        return NULL;
    }
};

你可能感兴趣的:(leetcode,算法,c++)