1、题目
2、思路
1.双指针:
定义两个指针:pre 和 cur;pre 在前,cur 在后;
每次让 pre 的 next 指向 cur ,实现一次局部反转;
局部反转完成之后, pre 和 cur 同时往前移动一个位置;
循环上述过程,直至 pre 到达链表尾部。
2.递归:而递归是先找到最后的节点,从后往前走。
3、双指针
(1)动画演示
初始情况下,cur 定义为空指针,pre 指向头结点 a,t 指向 pre 的 next 结点 b。
第一次循环
执行pre->next = cur;后,a 结点的 next 结点指向空指针。pre 和 cur 指针后移,分别指向 b 结点和 a 结点。
第二次循环
执行pre->next = cur;后,b 结点的 next 结点指向 a 结点。pre 和 cur 指针后移,分别指向 c 结点和 b 结点。
第三次循环
执行pre->next = cur;后,c 结点的 next 结点指向 b 结点。pre 和 cur 指针后移,分别指向 NULL 和 c 结点。
至此,循环结束,cur指向反链表的头节点。
(2) 代码
(3)时间和空间复杂度
时间复杂度O(n):算法使用一个循环来遍历链表,每个节点都被访问一次,因此时间复杂度是线性的,即O(n),其中n是链表的长度。
空间复杂度O(1):算法只需要使用常数级别的额外空间来存储一些指针变量,不随输入规模n的增加而增加,因此空间复杂度是O(1)。
4、递归
(1)动画演示
首先是我们本来给定的链表:
开始递归,到最深处,newhead有值了
然后开始回溯,L向前移动
继续回溯,最终完成逆置注意:如果链表有头节点,千万不能以头节点作为参数,否则头节点会被逆置成新链表的最后一个节点,而这个节点里的值是不可预料的。
这样就用递归完成了链表的逆置。
(2)代码
(3)时间和空间复杂度
时间复杂度:
递归算法的时间复杂度通常是O(n),其中n是链表的长度。在您的递归函数中,每个节点都会被访问一次,然后递归调用会将链表拆分为较小的部分,每部分都会被逆置。因此,总的时间复杂度是O(n)。
空间复杂度:
递归调用会使用系统的堆栈空间来存储每一级递归的参数和局部变量。在您的递归函数中,每次递归调用都会将当前节点的指针存储在堆栈上,因此空间复杂度也是O(n)。