/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { if(n<=0)return NULL; if(n==0)return NULL; ListNode dumphead(0); dumphead.next = head; ListNode* fast = &dumphead; ListNode* slow = &dumphead; while(n--) {fast = fast->next;} while(fast->next!=NULL) { fast = fast->next; slow = slow->next; } ListNode *tmp = slow->next; slow->next = slow->next->next; delete tmp; head = dumphead.next;//请问为啥要加上这一句呢?这个函数没有对head修改啊。。。 return head; } }; |
|
8分 |
没有上下文代码,所以没看太明白。
你这个函数的名字叫removeNthFromEnd,估计跟删除有关。 所以,删除之后,head要修改。 |
8分 |
函数功能是去除链表倒数第N个结点,算法很简单,就是建两个指针,一个快指针,一个慢指针
快指针先走N步,然后快慢指针同时走,直到快指针的下一个指针为空,则慢指针的下一个指针即为倒数第N个 把它删除即可 具体为什么要这一句 head = dumphead.next; |
对 |
|
8分 |
head = dumphead.next;//请问为啥要加上这一句呢?这个函数没有对head修改啊。。。
有一种情况 删除的倒数第n个元素是头指针 程序还有问题 假如链表的长度小于n呢 |
1分 |
貌似程序问题不少,可以多跑几次,输入不同的长度的结点来测试一下
|
8分 |
// 如果slow不动 , 即slow->next==head 下面语句将delete head ListNode *tmp = slow->next; slow->next = slow->next->next; delete tmp; return head; //这里head是无效指针 |
8分 |
不要比较n与链表的长度吗?
|
50分 |
dumphead.next = head;
dumphead.next就是指向head 按字面代码来说,那句根本就是不必要的(但是请考虑删除第一个节点的情况) 所以这句代码是必要的,使程序删除第一个节点时程序的正确性! dumphead next1 next2 如果删除 next1,其实头指针指向next2,但是head依然是指向next1 的内存块的,所以必须把删除后的dumphead->next(即next2地址赋值给head 再有 if(n<=0)return NULL; //if(n==0)return NULL; //n <= 0判断已经包含了,所以这是多余代码 ListNode dumphead(0); dumphead.next = head; ListNode* fast = &dumphead; ListNode* slow = &dumphead; //while(n--) //应该判断fast是否为空,空则返回NULL,原因是当n大于head元素个数的时候,将让程序奔溃 while(n-- && fast != NULL) {fast = fast->next;} |
9分 |
看了各位大神的评论,才发现这道题要考虑的地方还不少
1.注意链表长度小于N的情况!链表长度小于N时,提示,返回NULL 2.保证程序删除第一个节点,即head时,程序的正确性 当删除的是head结点时,显然应该返回head结点的下一个结点! 下面是自己写的程序,当练练手 /** http://bbs.csdn.net/topics/391029228 */ #include <stdio.h> #include <stdlib.h> #include <iostream> #include <sstream> using namespace std; struct ListNode{ ListNode * next; int value; }; ListNode* head=new ListNode(); /** 函数:removeNthFromEnd 功能:去除链表倒数第N个结点 */ ListNode* removeNthFromEnd(ListNode* head, int m) { int n=m; if(n<=0)return NULL; ListNode * dumphead=new ListNode();; dumphead->next = head; ListNode* fast = dumphead; ListNode* slow = dumphead; /* 注意链表长度小于N的情况! 链表长度小于N,提示,返回NULL */ while(n--) { if(NULL!=fast->next) fast = fast->next; else{ cout<<"链表长度小于"<<m<<endl; return NULL; } } while(fast->next!=NULL) { fast = fast->next; slow = slow->next; } ListNode *tmp = slow->next; slow->next = slow->next->next; delete tmp; /** 保证程序删除第一个节点,即head时,程序的正确性 当删除的是head结点时,显然应该返回head结点的下一个结点! */ head = dumphead->next; return head; } /** 遍历链表 */ void goThroughList(ListNode *head){ if(NULL==head) return; ListNode *test=new ListNode(); test=head; while(NULL!=test){ cout<<test->value<<endl; if(NULL==test->next) break; else test=test->next; } } void initList(){ int i = 1; head->value=i++; ListNode* index=new ListNode(); index->value=i++; head->next=index; for(;i<9;i++){ ListNode *last=new ListNode(); last->value=i; index->next=last; index=last; } } int main() { initList(); cout<<"原链表"<<endl; goThroughList(head); int nth = 10; head=removeNthFromEnd(head,nth); if(NULL!=head){ cout<<"去除倒数第"<<nth<<"个结点后的链表"<<endl; goThroughList(head); } system("pause"); return 0; } |