起因是正在做力扣的链表题目,做到第203题的时候,想到的是用迭代的方法求解的,如下:
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//创建一个虚拟头节点,就可以省略掉判断原始头节点的步骤了
ListNode *first=new ListNode(-1);
first->next=head;
ListNode *cur=first;
while(cur!=NULL&&cur->next!=NULL){
if(cur->next->val==val){
ListNode *tmp=cur->next;
cur->next=cur->next->next;
delete tmp; //记得删除内存占用
}
else cur=cur->next;
}
head=first->next;
delete first;
return head;
}
};
之后看了官方的解题思路里,有递归的方法做的,短短几行代码:
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if(head==NULL){
return head;
}
head->next=removeElements(head->next,val);
return head->val==val?head->next:head;
}
};
我都惊呆了,因为一直以来都不会用递归来作题,一直都理解不了怎么个递归法。
第一次接触递归,是在补《数据结构》课程的时候,有个很常见的求数组和的问题,用线性递归求解复杂度是0(n),而迭代的复杂度是0(n²),于是也只是简单的把代码记下来遇到问题用就行,直到又碰到了这个问题,给我整不会了。
下面可以分享一下我对递归详细的理解方法,比较笨拙但是能让自己看懂就好:
以203题官方递归解题代码为例,假定给的链表数是 [1,2,6,3,4,5,6]
如果从头往后分析,会发现每一次的head->next 都与后一项有关,不妨从尾往前一个一个来看
假设一共n项:
需要先明确两点:① 每一次递归部分都是会把这一次的head->next作为下一次的head
② 每一次的head->next都是下一次执行removeElements函数的返回值
这一题要求返回的只是指针,并不是把指针的数输出来了。
-第n项: head == NULL
head->val | head->next->val | return | |
开始 1→ | ↙ | 2→ | 1 结束 |
2→ | ↙ | 3→ | ↖2 |
6→ | ↙ | 3→ | ↖3 |
3→ | ↙ | 4→ | ↖3 |
4→ | ↙ | 5→ | ↖4 |
5→ | ↙ | NULL→ | ↖5 |
6→ | ↙ | NULL→ | ↖NULL |
NULL→ | 无了→ | ↖NULL |
箭头就是我大概理解的递归的一步一步的方向,很粗糙,但我总算捋清楚了!!!!