大家好,继续刷题日记,终于做到了链表,之前没有接触过,感觉很陌生,还有很多思路要学,先看一下题:
我一开始做,并没有扫描一次就实现的思路,我的思路很简单,先扫描一次算出总长度,然后再扫描一次删掉指定位置的节点。贴上代码:
/**
* 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) {
int num = 1;
ListNode *p = head;
ListNode *q;
while(p -> next != NULL){
q = p -> next;
p = q;
num++;
}
p = head;
if(n != num){
for(int i = 1;i < num - n;i++){
q = p -> next;
p = q;
}
ListNode *temp = p -> next;
if(p->next != NULL)
p -> next = temp ->next;
temp = nullptr;
return head;
}
else{
ListNode *temp = head -> next;
head = temp;
return head;
}
}
};
然后我去参考了别人的思路,发现只扫描一次是这样实现的:设置两个指针,都指向head,一个先扫描n - 1次,然后两个一起扫描,当第一个指向末尾的时候第二个指针就能找到要删除的节点,觉得很厉害,附上代码:
/**
* 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) {
ListNode* deleNode=head;
ListNode* last=head;
ListNode* temp;
//删除尾节点
if(n==1)
{
if(head->next==nullptr)
return nullptr;
else
{
last=last->next;
//找尾节点
while(last->next!=nullptr)
{
last=last->next;
deleNode=deleNode->next;
}
//删除尾节点
deleNode->next=nullptr;
return head;
}
}
else
{
//移动n个节点
for(int i=0;i<n-1;i++)
{
last=last->next;
}
//找尾节点
while(last->next!=nullptr)
{
last=last->next;
deleNode=deleNode->next;
}
//删除倒数第n个节点
temp=deleNode->next;
deleNode->val=deleNode->next->val;
deleNode->next=deleNode->next->next;
temp->next=nullptr;
}
return head;
}
};
还有一点想记录的是nullptr,这是专门指空指针的,比NULL更方便一些,因为NULL在编译时被看做是0,有时候会造成歧义,nullptr就不会,因此在针对指针为空的情况时用nullptr会更好一些。
还有很多要学习,共勉,我们下期见!