题目(leecode T206):反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
方法:改变链表指针方向
思路:拿到这道题我的第一反应是新创建一个链表,遍历原始链表,一个个的拿下节点在一个个的通过头插法插入新的链表中。但看了题解发现这样是对内存空间的浪费,实际上有更好的办法。
双指针法,分析题目我们发现,其实只需要改变每个节点指针的方向,将每个指向下一个位置的节点指向前一个即可完成题目。首先定义一个cur指针指向head的位置,定义一temp指向用来向后遍历,保存cur指针下一个要去的位置(因为cur指针要改变指针方向,所以需要一个指针用来帮他指向原来的路),定义一个pre指针,刚开始pre指针指向空值。随后执行cur的循环,先用temp保存位置,断开cur的指针指向pre, pre=cur,cur=temp。一直执行到空
题解:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* temp;
ListNode* cur = head;
ListNode* pre = NULL;
while(cur){
temp = cur -> next;
cur -> next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};
本题还可以使用递归的方式解题,不过递归的方式一般都比较抽象难以理解,还是更喜欢非递归的方式。但是还是要学习一下这种思想,毕竟有的题确实使用递归的方式会更简单。
class Solution {
public:
ListNode* reverse(ListNode* pre,ListNode* cur){
if(cur == NULL) return pre;
ListNode* temp = cur->next;
cur->next = pre;
// 可以和双指针法的代码进行对比,如下递归的写法,其实就是做了这两步
// pre = cur;
// cur = temp;
return reverse(cur,temp);
}
ListNode* reverseList(ListNode* head) { // ListNode* cur = head;ListNode* pre = NULL;
return reverse(NULL, head);
}
};