思路:
关于链表问题,特别是类似第几个这种问题,常常用双指针进行解题!
题目要求我们删除倒数第n个节点,我们自然需要找到倒数第n个节点,同时,把倒数第n+1个节点和n-1个节点进行连接,这样就达到删除的效果了。
重点在于查找,以及表示n+1个节点。
如何查找?这里用快慢指针进行查找,我们希望达成的目标是找到并且表示n+1个节点。
逆向思维,假设我们找到了,然后用慢指针slow表示了倒数第n+1个节点。此时快指针如何是如何告诉我们找到了倒数第n个节点?快指针以哪一种统一的形来标示着找到呢?
灵光一现,让快指针指向链表结尾空指针就可以啦!
此时我们发现快慢指针之间的距离是?没错,都是n+1个节点!
惊喜!这个结果状态被我们发现了!回推初始状态,自然是慢指针slow指向开始,快指针指向之后n+1个节点。
完成!
细节:
如果删除的是头节点怎么办?自然要用到虚拟头节点啦!
代码如下:
class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* vh=new ListNode(); vh->next=head; ListNode* f=vh; ListNode* s=vh; for(n;n>=0;n--,f=f->next){ } for(f;f;f=f->next,s=s->next){ } s->next=s->next->next; return vh->next; } };
class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n){ if(dfs(head,n)==-1) return head; return head->next; } int dfs(ListNode* head, int n){ if(!head) return 0; int t=dfs(head->next,n); if(t==-1) return -1; if(t==n){ head->next =head->next->next; return -1; } return t+1; } };
关于我热衷于递归这件事,我是不会让你们知道的。