代码随想录算法训练营第4天|24.两两交换链表的节点、19.删除链表倒数第N个节点、 面试题 02.07. 链表相交、 142.环形链表II
24.两两交换链表的节点
19.删除链表倒数第N个节点
这个题我刚开始的做法是遍历一遍链表,然后得出链表的长度,然后在计算正向应该删除哪个位置的元素。这样的解决方法代码十分冗长,而且需要定义很多指针,很麻烦。
这个题较优的解决方案应该是使用快慢指针,整体的思路是让快指针先走N步,然后快慢指针在一起走,知道快指针fast走到链表的尾部NULL,此时,慢指针slow刚好走到目标节点的前部,即可删除指定元素,代码如下:
点击查看代码
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
//定义虚拟头节点dummy 并初始化使其指向head
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->val = 0;
dummy->next = head;
//定义 fast slow 双指针
struct ListNode* fast = head;
struct ListNode* slow = dummy;
for (int i = 0; i < n; ++i) {
fast = fast->next;
}
while (fast) {
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;//删除倒数第n个节点
head = dummy->next;
free(dummy);//删除虚拟节点dummy
return head;
}
点击查看代码
ListNode *detectCycle(ListNode *head) {
ListNode *fast = head, *slow = head;
while (fast && fast->next) {
// 这里判断两个指针是否相等,所以移位操作放在前面
slow = slow->next;
fast = fast->next->next;
if (slow == fast) { // 相交,开始找环形入口:分别从头部和从交点出发,找到相遇的点就是环形入口
ListNode *f = fast, *h = head;
while (f != h) f = f->next, h = h->next;
return h;
}
}
return NULL;
}
浙公网安备 33010602011771号