图解反转链表的4种方法


声明:本文为博主原创文章,未经允许不得转载。如有问题,欢迎指正!

206. 反转链表 (简单)
题目描述:

反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
链接:https://leetcode-cn.com/problems/reverse-linked-list/

方法一:

遍历原链表,把“当前结点”按照头插法添加到新链表中。思路简单,图解略去。

 / /java代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
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代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
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 时具体的双指针操作过程示例:
在这里插入图片描述

方法三:

迭代法

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
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 时具体的迭代过程示例:
在这里插入图片描述

方法四:

递归解法:递归解法可由迭代演化过来。(大部分迭代和递归都可以相互转化)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
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 时主要的调用和回退过程(橙色结点为递归或回退到的“当前结点”):
在这里插入图片描述

上一篇博客:leetcode 78 子集 (位运算)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值