剑指offer:反转链表

题目描述

输入一个链表,反转链表后,输出新链表的表头。

思路1:借用外部空间

题目并没有要求原地反转,所以可以采用借外部空间反转,可以将单链表存储为数组,借用数组的索引倒序输出实现反转功能。但这个方法需要额外空间,且需要进行两次遍历,时间和空间复杂度均比较高。

import java.util.ArrayList;
public class Solution {
    public ListNode ReverseList(ListNode head) {
      if(head==null){
            return null;
        }
        ArrayList<ListNode> nodeList=new ArrayList<>();
        while(head!=null){
            nodeList.add(head);
            head=head.next;
        }
        int startIndex=nodeList.size()-1;
        for (int i = startIndex; i >=0; i--) {
            ListNode node=nodeList.get(i);
            if(i==0){
                node.next=null;
            }
            else{
                node.next=nodeList.get(i-1);
            }
             
        }
        //现在头结点是原来的尾节点
        head=nodeList.get(startIndex);
        return head;
 
    }
}

借用外部空间实现,应该用堆栈也可以。先遍历链表中的每个元素,然后将它们一个个压入堆栈,在新建一个新的链表,把元素逐个从链表中弹出(同时改变指针指向)。

思路2:递归法

逐层确定当前节点有没有next节点,若为空,则表明已经递归到最后一个节点,将该节点的next指向它的父节点,在递归栈中以此类推。

1.先找到最后一个节点,然后从最后一个节点进行反转,当前节点进行反转时,其后面的节点已经完成反转了,不用管。
2.最后返回原来的最后一个节点,即为反转后的头结点。

下面代码中,head.next是5,head是4,而5的next是null,所以递归返回时,head为4,newHead为5.然后根据这个来改变指针指向;

public class Solution {
    public ListNode ReverseList(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }else{
            ListNode newhead=ReverseList(head.next);
            head.next.next=head;//实现指针反转,将后一个节点的next指向它的前一个节点
            head.next=null;//这两句最后的实现效果是null←head←head.next
            return newhead;
        }
 
    }
}

思路3.迭代法

使用2个指针,把一个链表分成俩个部分, pre是已经反转部分, curr是为反转部分,然后通过俩个指针的配合,不断的右移直到全部反转
1.设置两个指针pre,curr分别指向前一节点和当前节点(第一次迭代,前一节点为null,当前节点为head节点),
2.先将curr的下一节点next记录下来。再让当前节点指向上一节点。(改变头节点的指针指向)
3.将pre和curr分别往后移动,pre指针对应curr,curr指针对应next,然后开始下轮的迭代(逐步去改变每一个节点 的指针指向)

 

public class Solution {
    public ListNode ReverseList(ListNode head) {
        if(head==null){
            return null;
        }
        ListNode preNode=null;
        ListNode currNode=head;
        while(currNode!=null){
            ListNode nextNode=currNode.next;
            currNode.next=preNode;//用来改变迭代到的每个元素的指针的指向
            preNode=currNode;
            currNode=nextNode;
        }
        return preNode;
         
 
    }

参考:https://www.cnblogs.com/edisonchou/p/4769537.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值