19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第n
个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1 输出:[]
示例 3:
输入:head = [1,2], n = 1 输出:[1]
提示:
- 链表中结点的数目为
sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
解题思路:
采用快慢指针,快指针先走n步,慢指针开始和快指针同步移动到next,当快指针到达链表尾部时,慢指针刚好移动到倒数第n-1个节点。
初始状态:(快慢指针都指向头结点所指节点)
快指针向前走4步后,N变为0:
快指针再向前走一步,此时慢指针向前走一步:
当快指针都到未节点时,慢指针走到倒数第n-1个节点:
删除倒数第N个节点后的链表如下:
1 #include <iostream> 2 #include <vector> 3 4 using namespace std; 5 6 class ListNode { 7 public: 8 ListNode() : val(0), next(nullptr) {} 9 ListNode(int x) : val(x), next(nullptr) {} 10 ListNode(int x, ListNode *next) : val(x), next(next) {} 11 12 public: 13 int val; 14 ListNode *next; 15 }; 16 17 class Solution { 18 public: 19 ListNode* removeNthFromEnd(ListNode* head, int n) { 20 ListNode *fast = head; 21 ListNode *slow = head; 22 //慢指针比快指针慢N步,那么快指针指向末尾的null时,慢指针刚好指向要删除结点的前驱结点 23 while (fast->next != nullptr) { 24 fast = fast->next; 25 if (n == 0) { 26 slow = slow->next; 27 } else { 28 n--; 29 } 30 } 31 if (n != 0) { //没追上,说明删除的是头指针 32 return head->next; 33 } else { 34 slow->next = slow->next->next; 35 } 36 return head; 37 } 38 void insertNodeAtTail(ListNode *&head, int val) { 39 ListNode *newNode = new ListNode(val); 40 ListNode *currentNode = head; 41 if (head == nullptr) { 42 head = newNode; 43 return; 44 } 45 while (currentNode->next != nullptr) { 46 currentNode = currentNode->next; 47 } 48 currentNode->next = newNode; 49 return; 50 } 51 void printfListNode(ListNode *head) { 52 while (head != nullptr) { 53 std::cout << head->val << "->"; 54 head = head->next; 55 } 56 std::cout << "NULL" << endl; 57 return; 58 } 59 }; 60 int main() 61 { 62 Solution *test = new Solution(); 63 vector<int> vec = {1, 2, 3, 4, 5, 6, 7 }; 64 ListNode *head = nullptr; 65 for (const auto &v : vec) { 66 test->insertNodeAtTail(head, v); 67 } 68 test->printfListNode(head); // 1->2->3->4->5->6->7->NULL 69 // 删除链表中非头结点 70 ListNode *headNodeAfterDelete = test->removeNthFromEnd(head, 4); 71 test->printfListNode(headNodeAfterDelete); // 1->2->3->5->6->7->NULL 72 // 删除头结点 73 headNodeAfterDelete = test->removeNthFromEnd(head, 6); 74 test->printfListNode(headNodeAfterDelete); // 2->3->5->6->7->NULL 75 delete test; 76 system("pause"); 77 return 0; 78 }
运行后结果: