力扣19. 删除链表的倒数第N个节点(两次遍历、加间隔一次遍历)

力扣19. 删除链表的倒数第N个节点(两次遍历、加间隔一次遍历)

https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?

一、两个遍历

复杂度分析

时间复杂度:O(L),该算法对列表进行了两次遍历,首先计算了列表的长度 L 其次找到第 (L - n)个结点。 操作执行了 2L−n 步,时间复杂度为 O(L)。

空间复杂度:O(1),我们只用了常量级的额外空间

Remove the nth element from a list

	ListNode* removeNthFromEnd(ListNode* head, int n)
	{
		//鲁棒性,链表为空
		if (head==nullptr || n<=0)
		{
			return head;
		}

		//获取链长
		ListNode* temp = head;
		int len = 0;
		while (temp != nullptr)
		{
			len++;
			temp = temp->next;
		}

		//刚好删的是第一个节点
		if (n==len)
		{
			return head->next;
		}

		//cur指针去到要删的节点前一个节点
		ListNode* cur = head;
		for (int i = 0; i<len - n-1; i++)
		{
			cur = cur->next;
		}
		//删除操作
		ListNode* del = cur->next;
		cur->next = del->next;
		return head;
	}

 

二、加间隔一次遍历

图来自一位大神,可以关注他的公众号

https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/dong-hua-tu-jie-leetcode-di-19-hao-wen-ti-shan-chu/

ListNode* removeNthFromEnd(ListNode* head, int n)
	{
		//鲁棒性,链表为空
		if (head == nullptr || n <= 0)
		{
			return head;
		}
		ListNode* p = head;
		ListNode* q = head;
		for (int i = 0; i <= n; i++)
		{
			q = q->next;
		}
		while (q != nullptr)
		{
			p = p->next;
			q = q->next;
		}
		//删除操作
		p->next = p->next->next;
		return head;
	}

三、汇总

#include "stdafx.h"

struct ListNode
{
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}

};

class Solution
{
public:
	ListNode* removeNthFromEnd2(ListNode* head, int n)
	{
		//鲁棒性,链表为空
		if (head == nullptr || n <= 0)
		{
			return head;
		}

		//获取链长
		ListNode* temp = head;
		int len = 0;
		while (temp != nullptr)
		{
			len++;
			temp = temp->next;
		}

		//刚好删的是第一个节点
		if (n == len)
		{
			return head->next;
		}

		//cur指针去到要删的节点前一个节点
		ListNode* cur = head;
		for (int i = 0; i < len - n - 1; i++)
		{
			cur = cur->next;
		}
		//删除操作
		ListNode* del = cur->next;
		cur->next = del->next;
		return head;
	}
	ListNode* removeNthFromEnd1(ListNode* head, int n)
	{
		//鲁棒性,链表为空
		if (head == nullptr || n <= 0)
		{
			return head;
		}
		ListNode* p = head;
		ListNode* q = head;
		for (int i = 0; i <= n; i++)
		{
			q = q->next;
		}
		while (q != nullptr)
		{
			p = p->next;
			q = q->next;
		}
		//删除操作
		p->next = p->next->next;
		return head;
	}
};

int main()
{
	Solution s;
	ListNode head[5] = { 1,2,3,4,5 };
	head[0].next = &head[1];
	head[1].next = &head[2];
	head[2].next = &head[3];
	head[3].next = &head[4];
	auto result1 = s.removeNthFromEnd1(head, 2);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35683407/article/details/105829250