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

206.反转链表

力扣题目链接:反转链表

昨天写反转链表的时候漏了一个递归法,今天补上。

class Solution {
public:
	ListNode* reverse(ListNode* pre, ListNode* cur) {
		if (cur == nullptr) return pre;
		ListNode* tmp = cur->next;
		cur->next = pre;
		return reverse(cur, tmp);
	}
	ListNode* reverseList(ListNode* head) {
		return reverse(nullptr, head);
	}
};

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

力扣题目链接:两两交换链表中的节点

这一题原理其实很简单,但是很考验细心程度,稍不注意就会把一堆next给接错。

class Solution {
public:
	ListNode* swapPairs(ListNode* head) {
		ListNode* pummyHead = new ListNode(0, head);
		ListNode* cur = pummyHead;
		while (cur->next != nullptr && cur->next->next != nullptr) {
			ListNode* tmp1 = cur->next;
			ListNode* tmp2 = cur->next->next->next;
			cur->next = cur->next->next;
			cur->next->next = tmp1;
			tmp1->next = tmp2;
			cur = cur->next->next;
		}
		cur = pummyHead->next;
		delete pummyHead;
		return cur;
	}
};

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

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

这一题其实一开始我是没什么思路的,我能想到的就是先记录链表的长度len,然后再从头移动len-n位删除。不过这样就要循环两轮,时间复杂度是O(2n)。

后面看了卡哥提供的双指针法思路才知道原来可以使用双指针法。

class Solution {
public:
	ListNode* removeNthFromEnd(ListNode* head, int n) {
		ListNode* pummyHead = new ListNode(0, head);
		ListNode* slow = pummyHead;
		ListNode* fast = pummyHead;
		while (n--) {
			if (fast->next == nullptr) {
				delete pummyHead;
				return head;
			}
			fast = fast->next;
		}
		while (fast->next != nullptr) {
			fast = fast->next;
			slow = slow->next;
		}
		ListNode* tmp = slow->next;
		slow->next = slow->next->next;
		delete tmp;
		slow = pummyHead->next;
		delete pummyHead;
		return slow;
	}
};

面试题 02.07. 链表相交

力扣题目链接:链表相交

于是乎一开始我又想的是暴力循环法,一个个节点去对是否有相同节点,这样的话时间复杂度是O(n²)。后面依旧还是看了卡哥的思路才想起来用双指针法。

看来双指针法我掌握的还是太差了,好多妙用都联想不起来。

class Solution {
public:
	ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) {
		int lenA = 0, lenB = 0;
		ListNode* pummyHeadA = new ListNode(0, headA);
		ListNode* pummyHeadB = new ListNode(0, headB);
		ListNode* curA = pummyHeadA, * curB = pummyHeadB;
		while (curA->next != nullptr) {
			lenA++;
			curA = curA->next;
		}
		curA = pummyHeadA;
		while (curB->next != nullptr) {
			lenB++;
			curB = curB->next;
		}
		curB = pummyHeadB;
		if (lenA > lenB) {
			lenA = lenA - lenB;
			while (lenA--) {
				curA = curA->next;
			}
		}
		else if (lenB > lenA) {
			lenB = lenB - lenA;
			while (lenB--) {
				curB = curB->next;
			}
		}
		while (curA->next != nullptr && curB->next != nullptr) {
			if (curA->next == curB->next) {
				curA = curA->next;
				delete pummyHeadA;
				delete pummyHeadB;
				return curA;
			}
			curA = curA->next;
			curB = curB->next;
		}
		return nullptr;
	}
};

142.环形链表II

力扣题目链接:环形链表II

没什么好说的,完全没有思路,不是看卡哥讲解根本想不到x=z

class Solution {
public:
	ListNode* detectCycle(ListNode* head) {
		ListNode* fast = head, * slow = head;
		while (true) {
			if (fast == nullptr || fast->next == nullptr) {
				return nullptr;
			}
			fast = fast->next->next;
			slow = slow->next;
			if (fast == slow) {
				break;
			}
		}
		ListNode* index1 = fast;
		ListNode* index2 = head;
		while (index1 != index2) {
			index1 = index1->next;
			index2 = index2->next;
		}
		return index1;
	}
};

今天不会的题目实在是太多了,需要好好消化一番……

链表题目比我想象中的要复杂得多。

你可能感兴趣的:(算法,链表,数据结构)