反转单链表

题目描述

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

来自leetcode: https://leetcode-cn.com/problems/reverse-linked-list/
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

栗子:

在这里插入图片描述

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


问题解决

1.方法一

边遍历原链表进行取值,边创建一个新链表进行头插即可。(前提,没有要求空间复杂度)

代码如下(示例):

public ListNode reverseList(ListNode head){
        if(head==null||head.next==null){
            return head;
        }
        //创建新链表的虚拟头节点
        ListNode dummyHead=new ListNode(5001);
        // 边遍历原链表,边头插新链表
        while(head!=null){
            ListNode node=new ListNode(head.val);
            node.next=dummyHead.next;
            dummyHead.next=node;
           head=head.next;
        }
        return dummyHead.next;
    }

2.方法二

原地移动(此时空间复杂度为O(1)–只能改变原链表的指向)

边遍历原链表,边让原链表的next不再指向后继转而指向其前驱。

因为牵扯到两个节点的反转指向,所以需要定义两个引用
cur-表示当需要处理的节点
prev-当前节点的前驱
cur.next=prev;(反转指向)
代码如下(示例):

 public ListNode reverseList(ListNode head) {
        if(head==null||head.next==null){
           return head;
        }
       ListNode prev=null;
       //当前需要处理的节点(需要反转)
       ListNode cur=head;
       while(cur!=null) {
           //暂存下一个需要处理的节点
          ListNode next=cur.next;
          cur.next=prev;
          prev=cur;
         cur=next;
        }
        return prev;
    }

:1.暂存下一节点的原因:在操作完cur.next=prev之后,cur与连接到原来的链表就断开了,要进行下一次的两个节点的反转,就会找不到下一个节点,所以需要先用next来暂存。

3.方法三

为什么可以使用递归
1.把反转链表这个大问题拆成两个子问题, 一个是头节点,另一个是除了头节点剩下的子链表。
2.子问题的求解方式和大问题一样。
3.存在最小子问题,即只剩一个节点,便不用再反转。
传入一个以head为头节点的链表方法就可以将此链表反转并且返回反转后的链表头节点

public ListNode reverseList(ListNode head) {
//递归终止条件
 if(head==null||head.next==null){
         return head;
        }
     ListNode sec=head.next;
      //反转第二个节点之后的子链表
     ListNode newHead=reverseList(head.next);
     sec.next=head;
      head.next=null;
      return newHead;
    }

需要注意的是
头节点的下一个节点必须指向 null。如果忽略了这一点,链表中可能会产生环。


链表具有天然的递归性质。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值