给定一个链表,删除链表的倒数第 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; }