力扣206.单链表的反转-多方法对比超级详细
方法1-栈遍历
先使用栈依次保存整个原链表从head到tail的数值
然后创建一个新的链表,链表的数值依次从栈中弹出。
方法2-头插法
时间复杂度为 𝑂(𝑛),空间复杂度为 𝑂(𝑛)。
● 创建一个新的链表头部newhead,初始状态是NULL;
● 创建一个临时节点temp,依次保存原链表的数据;
● temp每读取一次数据后,temp的next将指向新链表的头部newhead,即新的节点temp插在了新链表的头部(头插)
○ 初始状态时,新的链表头newhead为NULL,temp读取到原链表的节点的数据后next指向newhead(即temp的next指向NULL)
○ 经历过几次迭代后,新的链表头newhead后面连接着一大堆的节点,temp读取到原链表的节点的数据后next指向新链表的头节点newhead
● 当前的temp节点更新为新的链表头部newhead;
● 原链表的头节点向后遍历,更新节点
从头到尾依次遍历整个链表,
temp每次在插入节点的时候从新链表的头部进行插入。
/**
* 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 *newhead = NULL;
// 用于存储原链表数据的临时节点
ListNode *temp = NULL;
while (head != NULL) {
// temp = (ListNode*)malloc(sizeof(ListNode));
temp = new ListNode(head->val);
// temp 获取当前head的数据
temp->val = head->val;
// temp指向newhead:temp在前,newhead在后(头插)
// newhead是新的链表的头节点:因为是头插,所以新的节点
// 要插在newhead的前面
temp->next = newhead;
// temp变成新的newhead(temp在前所以变成新的头节点)
newhead = temp;
// 原head向后遍历
head = head->next;
}
return newhead;
}
};
方法3-直接在原链表中进行反转
时间复杂度为 𝑂(𝑛),空间复杂度为 𝑂(1)
文字描述:
用到两个辅助节点:
pre指向反转后的新节点的头节点,初始值为空,
next记录反转前链表中当前节点(head)的next节点,初始值为空
● 在程序for循环开始后,首先记录下反转前链表中当前节点(head)的next节点,
因为后面的操作要对head.next的值进行修改;
● 将反转前链表中当前节点(head)的next,指向新链表的头节点(反转的关键);
○ 在第一次时,新链表的头节点pre为空;
○ 在迭代几次后,pre为反转后链表的头节点,原链表的head指向反转后的链表头节点;
● 反转前链表中当前节点(head)变成新链表的头节点,并且更新head的值向下遍历;
/**
* 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) {
// pre指向反转后的新节点
ListNode *pre = NULL;
ListNode *next = NULL;
while (head != NULL) {
// next用来临时记录原链表头节点的next,
// 因为后面要对head.next进行更改
next = head->next;
// head是原链表的当前节点,让它的next指向新链表的头节点
head->next = pre;
// 原链表的当前节点head变成新链表的头节点
pre = head;
// head节点向下遍历
head = next;
}
return pre;
}
};
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
// pre指向反转后的新节点
ListNode pre = null;
ListNode next = null;
while(head!=null)
{
// next用来临时记录原链表头节点的next,因为后面要对head.next进行更改
next = head.next;
// head是原链表的当前节点,让它的next指向新链表的头节点
head.next = pre;
// 原链表的当前节点head变成新链表的头节点
pre = head;
// head节点向下遍历
head = next;
}
return pre;
}
}