题目

迭代解法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* curr = head;
ListNode* pro = NULL;
while(curr){
ListNode* next = curr->next;
curr->next = pro;
pro = curr;
curr = next;
}
return pro;
}
};
这里我们运用迭代的方法,定义一个curr指针暂存头节点,然后定义curr的前驱节点和后继节点,利用这三个节点,实现链表的逆序,就是让每个节点的指针域反转。
其一定义三个指针,让curr的前驱节点指向NULL;
其二利用while循环,首先利用next暂存curr的后继节点,然后让curr的后继节点置为pro,紧接着让pro指向curr对应地址,再让curr指向next对应地址,循环往复,节点就逆转了。
这里注意,当节点指针域改变以后,就不能利用Node->next来偏移指针了,这也是定义后继节点的目的。

递归解法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==NULL||head->next==NULL){
return head;
}
ListNode* newhead = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return newhead;
}
};
经过两天的鏖战,终于是拿下了这个递归的解法,我现在对这个题目是完全理解啦,递归真是个美妙的解法,神奇且魔幻,接下来我将以另外的形式呈现我的想法:
//1 ->2 ->3 ->4 ->5
//h1 h2 h3 h4 h5
ListNode* hanshu1(ListNode* h1){
if(head==NULL||head->next==NULL){
return h1;
}
ListNode* h2 = h1->next;
ListNode* newh = hanshu2(h2);
h1->next->next = h1;
h1->next = NULL;
return newh;
}
ListNode* hanshu2(ListNode* h2){
if(head==NULL||head->next==NULL){
return h2;
}
ListNode* h3 = h2->next;
ListNode* newh = hanshu3(h3);
h2->next->next = h2
h2->next = NULL;
return newh;
}
ListNode* hanshu3(ListNode* h3){
if(head==NULL||head->next==NULL){
return h3;
}
ListNode* h4 = h3->next;
ListNode* newh = hanshu4(h4);
h3->next->next = h3
h3->next = NULL;
return newh;
}
ListNode* hanshu4(ListNode* h4){
if(head==NULL||head->next==NULL){
return h4;
}
ListNode* h5 = h4->next;
ListNode* newh = hanshu5(h5);
h4->next->next = h4
h4->next = NULL;
return newh;
}
ListNode* hanshu5(ListNode* h5){
if(head==NULL||head->next==NULL){
return h5;
}
ListNode* h6 = h5->next;
ListNode* newh = hanshu6(h6);
h5->next->next = h5
h5->next = NULL;
return newh;
}
ListNode* hanshu6(ListNode* h6){
if(head==NULL||head->next==NULL){
return h6;
}
ListNode* h7 = h6->next;
ListNode* newh = hanshu7(h7);
h6->next->next = h6
h6->next = NULL;
return newh;
}
其实呢,就可以看作是一个函数接一个函数的嵌套,函数不断被调用,直到if语句触发,返回目标头节点,然后就一层一层往外返回,在每一次返回之后,改变指针域朝向,实现链表反转。
上面的演示代码中,hanshu1到hanshu6其实代表的都是同一个函数,这个函数以不同的参数传入,被调用了6次,然后一层一层地返回,实现整个过程。
我举一个例子,一群矿工一个接一个地排成一排,进入一个洞穴,顺序是第一个先进去,然后第二个人,紧接着第三个人。。。当第一个人走到洞穴尽头的时候,就会转身告诉第二个人,紧接着第二个人转身告诉第三个人,最终告诉最后一个人,他们才能出去。
反思
1.考察知识点:单向链表,前驱指针和后继指针
2.踩的坑:对于指针的利用还不够规范,思路不够正式;
3.待会儿补充递归法。
508

被折叠的 条评论
为什么被折叠?



