链表反转的三种解法:
一、题目要求:
ListNode节点类:
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;
}
}
二、解题思路及代码
思路1:使用“递归算法”,因为递归算法能够不断调用自身,实现进入到最后一个节点。当last为最后一个节点是,此时的head会是倒数第二个节点。代码中head即是倒数第二个节点元素(元素4),head.next即是最后一个节点(元素5),那么head.next.next即是(元素5)的下一个节点逆向指回了head节点(元素4)。当逆向指回后,将倒数第二个元素head.next指向null。由于是递归调用,会从后往前一次逆转。
演示:
代码:
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null){
return head;
}
// 递归实现
ListNode last = reverseList(head.next); // 最后一个节点
head.next.next = head;
head.next = null;
return last;
}
}
特点:时间较优,空间较差
思路2:使用三个节点分别记录:head-旧链表头;n1-新链表头;o2-暂存旧链表第二个节点。每次都是用o2暂存head.next。将head移动到n1。最后返回n1即可
演示:
代码2:
class Solution {
public ListNode reverseList(ListNode head) {
// 使用三个节点的方法
ListNode n1 = null;
while(head != null){
ListNode o2 = head.next;
head.next = n1;
n1 = head;
head = o2;
}
return n1;
}
特点: 不用创建新的节点,面向过程
总结:链表的解题关键在于是否要创建新的链表,以及next指向要清楚 。其他变成语言用这个思路也一样。