Given a linked list, remove the nth node from the end of list and return its head.
For example,
Given linked list: 1->2->3->4->5, and n = 2.
After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
解法 1:统计链表长度len,正向删除第len-n+1个节点。
1 /**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 * int val;
5 * ListNode *next;
6 * ListNode(int x) : val(x), next(NULL) {}
7 * };
8 */
9 class Solution {
10 public:
11 ListNode *removeNthFromEnd(ListNode *head, int n) {
12 // Start typing your C/C++ solution below
13 // DO NOT write int main() function
14 if(!head){
15 return head;
16 }
17 int len = 1;
18 ListNode *p = head;
19 while(p->next){
20 p = p->next;
21 len++;
22 }
23 ListNode *h = new ListNode(0);
24 h->next = head;
25 if(len == n){
26 return head->next;
27 }
28 if(len>n){
29 int step = len-n;
30 while(step > 0){
31 h = h->next;
32 step--;
33 }
34 h->next = h->next->next;
35 }
36 return head;
37 }
38 };
Run Status: Accepted!
Program Runtime: 36 milli secs
Progress: 207/207 test cases passed.
解法 2:递归方法,一次遍历 (in one pass)。
1 /**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 * int val;
5 * ListNode *next;
6 * ListNode(int x) : val(x), next(NULL) {}
7 * };
8 */
9 class Solution {
10 bool removeNthFromEnd(ListNode *head, ListNode *p, int n, int &len){
11 if(NULL == p){
12 len = 0;
13 return false;
14 }else{
15 if(!removeNthFromEnd(head, p->next, n, len)){
16 len++;
17 if(len == n && p == head){
18 return true;
19 }
20 if(len == n+1){
21 p->next = p->next->next;
22 return true;
23 }
24 return false;
25 }
26 return true;
27 }
28 }
29 public:
30 ListNode *removeNthFromEnd(ListNode *head, int n) {
31 // Start typing your C/C++ solution below
32 // DO NOT write int main() function
33 int len = 0;
34 ListNode *p = head;
35 removeNthFromEnd(head, p, n, len);
36 if(len == n){
37 return head->next;
38 }
39 return head;
40 }
41 };
Run Status: Accepted!
Program Runtime: 44 milli secs
Progress: 207/207 test cases passed.
更加优雅一点的方法:递归之前,在链表头部加一个“头指针 h”,最终统一地返回h->next 。
1 /**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 * int val;
5 * ListNode *next;
6 * ListNode(int x) : val(x), next(NULL) {}
7 * };
8 */
9 class Solution {
10 bool removeNthFromEnd(ListNode *p, int n, int &len){
11 if(NULL == p){
12 len = 0;
13 return false;
14 }else{
15 if(!removeNthFromEnd(p->next, n, len)){
16 len++;
17 if(len == n+1){
18 p->next = p->next->next;
19 return true;
20 }
21 return false;
22 }
23 return true;
24 }
25 }
26 public:
27 ListNode *removeNthFromEnd(ListNode *head, int n) {
28 // Start typing your C/C++ solution below
29 // DO NOT write int main() function
30 int len = 0;
31 ListNode *h = new ListNode(0);
32 h->next = head;
33 removeNthFromEnd(h, n, len);
34 return h->next;
35 }
36 };