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

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

示例:

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

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

给定的 n 保证是有效的。

进阶:

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

/*
解题思路:
比如我们首先要考虑的时,如何找到倒数第N个节点,由于只允许一次遍历,
所以不能用一次完整的遍历来统计链表中元素的个数,而是遍历到对应位置就应该移除了。
那么我们需要用两个指针来帮助我们解题,pre 和 cur 指针。
首先 cur 指针先向前走N步,如果此时 cur 指向空,说明N为链表的长度,则需要移除的为首元素,
那么此时返回 head->next 即可,如果 cur 存在,再继续往下走,此时 pre 指针也跟着走,
直到 cur 为最后一个元素时停止,此时 pre 指向要移除元素的前一个元素,我们再修改指针跳过需要移除的元素即可
*/
#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace	std;
struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}

};
class Solution {
public:
	ListNode* removeNthFromEnd(ListNode* head, int n) 
	{
		if (!head->next) return NULL;
		ListNode *pre = head, *cur = head;
		for (int i = 0; i < n; ++i) 
			cur = cur->next;
		if (!cur) 
			return head->next;
		while (cur->next) 
		{
			cur = cur->next;
			pre = pre->next;
		}
		pre->next = pre->next->next;
		return head;
	}
};
ListNode* CreateListNode(int arr[], int n)
{
	ListNode* head;
	head = new ListNode(arr[0]);
	ListNode* cur;
	cur = head;
	for (int i = 1; i < n; i++)
	{
		cur->next = new ListNode(arr[i]);
		cur = cur->next;
	}
	return head;
}
int main()
{
	int n;
	int m;
	cin >> n;
	cin >> m;
	int i;
	int a[100];
	for (i = 0; i < m; i++)
	{
		scanf("%d", &a[i]);
	}
	ListNode* head = CreateListNode(a, m);
	ListNode* head1 = Solution().removeNthFromEnd(head, n);
	while (head1 != NULL)
	{
	printf("%d ", head1->val);
	head1 = head1->next;
	}
	system("pause");
	return 0;
}

  

原文地址:https://www.cnblogs.com/277223178dudu/p/11407244.html