【LeetCode】链表之反转链表(一)

题目:
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:
在这里插入图片描述

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:
在这里插入图片描述

输入:head = [1,2]
输出:[2,1]
示例 3:

输入:head = []
输出:[]

(一)经典迭代

用while循环遍历列表,将每一个节点的指向改为前一个节点,把最后一个节点当作一个新的头节点返回。在遍历的过程中,由于当前节点的指向改变,我们就无法找到下一个节点。因此我们需要提前储存下一个节点。
详细代码及动态图:
在这里插入图片描述

public class Solution {
    public ListNode ReverseList(ListNode head) {
          //定义cur节点代表当前需要反转的节点,cur一开始处于头节点的位置
         ListNode cur=head;
         //定义prev为反转节点的前一个节点,即左边的节点,初始化为null
         ListNode prev=null;
         //循环条件为cur节点走完全部的节点
        while(cur!=null){
        //定义一个curNext节点,永远指向cur的下一个节点,防止丢失
            ListNode curNext=cur.next;
            //反转关键:将当前节点的指向改为前一个节点
            cur.next=prev;
            //prev向后到cur位置
            prev=cur;
            //cur向后到下一个需要反转的节点
            cur=curNext;
        }
        //prev最后所在的位置就是新的头节点。
        return prev;
    }
}

(二)用栈解决

栈的特点是先进后出。
反转链表可以利用这个特点,正向依次放入节点,最后依次弹出节点。
在这里插入图片描述

public class Solution {
    public ListNode ReverseList(ListNode head) {
        Stack<ListNode> stack=new Stack<>();
        //遍历列表,依次放入栈中
        while(head!=null){
            stack.push(head);
            head=head.next;
        }
        //如果是空链表,返回null
        if(stack.isEmpty()) return null;
        //node节点代表正在存放的节点
        ListNode node=stack.pop();
        //dummy作为新链表的头节点
        ListNode dummy=node;
        while(!stack.isEmpty()){
        //定义一个tmpNode节点暂时接受下一个弹出的节点
            ListNode tmpNode=stack.pop();
            //让node节点指向下一个节点
            node.next=tmpNode;
            //更新node节点
            node=node.next;
        }
        //置空最后一个节点的next,否则最后一个节点和倒数第二个节点会构成环
        node.next=null;
        return dummy;
    }
}

(三)双链表求解

创建一个新的链表,每次把原链表的头节点摘掉,放到新链表里当作头节点。过程如下图:
在这里插入图片描述
详细代码及解释:

public class Solution {
    public ListNode ReverseList(ListNode head) {
        //新链表头节点
        ListNode newHead=null;
        while(head!=null){
        //定义tmp暂时储存head的下一个节点
            ListNode tmp=head.next;
            //将head的指向改为新链表的头节点
            //就是将新链表挂到挂到head的后面
            head.next=newHead;
            //更新头节点
            newHead=head;
            //此时旧链表头节点的下一个节点成为头节点
            head=tmp;
        } 
        return newHead;
    }
}
(四)递归求解

递归解法最关键的一点是 :
每次递归后的返回都是将后序链表反转并返回头节点的引用。

详细过程如下:
在这里插入图片描述
代码如下:

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;
    }
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值