声明:本文为博主原创文章,未经允许不得转载。如有问题,欢迎指正!
206. 反转链表 (简单)
题目描述:
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
链接:https://leetcode-cn.com/problems/reverse-linked-list/
方法一:
遍历原链表,把“当前结点”按照头插法添加到新链表中。思路简单,图解略去。
/ /java代码
class Solution {
public ListNode reverseList(ListNode head) {
ListNode Reverse=null; / /定义新链表
ListNode temp=head; / /temp用于遍历
while(temp!=null){
ListNode cur=new ListNode(temp.val); / /生成新结点
if(Reverse==null) Reverse=cur; / /Reverse为空时直接指向新结点
else{ / /Reverse非空时执行头插:
ListNode p=Reverse; / /1.用p标记Reverse(记录头结点)
Reverse=cur; / /2.Reverse指向新结点cur (更改头结点)
Reverse.next=p; / /3.新的头结点与之前链表连接
}
temp=temp.next;
}
return Reverse;
}
}
方法二:
== 双指针解法== 既然是反转,就把原来的“指向”反过来。遍历链表,把当前结点cur指向cur的上一个结点,因为单向链表不能“由当前结点知道上一个结点”,故用pre记录前一个结点。如果只有前面的操作,那cur原本的后继结点就找不到了,故应该先用record将其保存。
/ /java代码
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur=head; / /cur用于遍历链表
ListNode pre=null;/ /pre为当前结点cur的上一个结点。初始化为null,因为最开始的pre最终变为尾
while(cur!=null){
ListNode record=cur.next; / /1.记录cur的下一个结点,以防在 cur.next=pre 后找不到“原来的下一个”
cur.next=pre; / /2.当前的“指针”指向上一个
pre=cur; / /3.pre后移
cur=record; / /4.cur指向下一个结点
}
return pre;
}
}
方法二图解
以下是链表为1->2->3->4->null 时具体的双指针操作过程示例:
方法二:
迭代法:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur=head;
if(head==null) return null;
while(head.next!=null){
ListNode record=head.next.next;
head.next.next=cur;
cur=head.next;
head.next=record;
}
return cur;
}
}
方法三图解
以下是链表为1->2->3->4->null 时具体的迭代过程示例:
方法四:
递归解法:递归解法可由迭代演化过来。(大部分迭代和递归都可以相互转化)
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->null 时主要的调用和回退过程(橙色结点为递归或回退到的“当前结点”):