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

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

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

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

class Solution{
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode * dummyHead = new ListNode(0);  //定义虚拟头节点
        dummyHead->next = head;
        ListNode *cur = dummyHead;
        while(cur->next && cur->next->next) {
            ListNode * tmp = cur->next;
            ListNode * tmp1 = cur->next->next->next;
            cur->next = cur->next->next;
            cur->next->next = tmp;
            cur->next->next->next = tmp1;
            cur = cur->next->next;
        }
        return dummyHead->next;
    }
};

本题小结:在进行交换时有点绕,最好画示意图,理清先后顺序。

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

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

class Solution {
public:
   ListNode* removeNthFromEnd(ListNode* head, int n) {  //双指针法,使用快慢指针间隔n个,通过快指针到达最后一个结点,然后进行删除
        ListNode *dummyHead = new ListNode(0);  //虚拟头节点
        dummyHead->next = head;
        //定义快慢指针
        ListNode *fast = dummyHead;
        ListNode *slow = dummyHead;
        while(n-- && fast) {  //先将快指针与慢指针拉开n个身位
            fast = fast->next;
        }
        while(fast->next) {  //保证快指针到最后结点
            slow = slow->next;
            fast = fast->next;
        }
        //删除操作
        ListNode *tmp = slow->next;
        slow->next = slow->next->next;
        delete tmp;
        return dummyHead->next;
    }
};

本题小结:由于单链表的特性,无法从后往前遍历,此题考虑采用快和慢双指针,先间隔n个身位,当快指针到达最后一个结点,慢指针到达删除结点的前一个结点,执行删除操作即可。

LeetCode 面试题 02.07题 链表相交

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

双指针法

class Solution {  //此题的含义是求取两个单链表相交的起始结点
public:
	ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {  //按题意,相交部分将一直延续到最后节点
		//因此仅需将两个单链表对其之后进行比较即可
		ListNode *curA = headA;
		ListNode *curB = headB;
		int lenA = 0;
		int lenB = 0;
		while (curA) {  //得到A的长度
			lenA++;
			curA = curA->next;
		}
		while (curB) {  //得到B的长度
			lenB++;
			curB = curB->next;
		}
		//将长度较长的单链表设置为A,方便调整
		curA = headA;
		curB = headB;
		if (lenA < lenB) {
			swap(lenA, lenB);
			swap(curA, curB);
		}
		//将A和B末尾对齐
		int gap = lenA - lenB;
		while (gap--) {
			curA = curA->next;
		}
		while (curA) {
			if (curA == curB) {
				return curA;
			}
			curA = curA->next;
			curB = curB->next;
		}
		return NULL;
	}
};

本题小结:要理解题意,相交部分将一直延续到最后节点,所以仅需判断起始节点位置,思路是先对齐,然后判断,要注意节点相等和数值相等

LeetCode 142题 环形链表II

题目链接: 142.环形链表II

双指针法

class Solution {
public:
    ListNode* detectCycle(ListNode *head) {
        ListNode * fast = head;  //定义快指针
        ListNode * slow = head;  //定义慢指针
        while(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 index2;
            }
        }
        return NULL;
    }
};

本题小结:此题首先考虑采用快慢双指针,然后判断环的存在,最后通过公式推导得出当头节点和快慢指针相遇结点再次共同相遇时,则为环的起始结点,返回即可。

你可能感兴趣的:(代码随想录二刷,链表,算法,数据结构)