手撸反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
定义节点类

public class ListNode {
    int val;
    ListNode next;// 下一个链表对象
    ListNode(int x) { val = x; } //赋值链表的值
}

第一种利用外部空间,申请一个动态扩容的数组或者容器,比如 ArrayList ,栈,都可以,遍历两次

public ListNode reverseList(ListNode head) {
    if(head==null||head.next==null){
        return head;
    }
    List<ListNode> list=new ArrayList<ListNode>();
    while(head!=null){
        list.add(head);//迭代链表,把node赋值给list
        head=head.next;//替换当前节点为下一个节点
    }
    int index=list.size()-1;
    ListNode next=null;
    ListNode node=list.get(index);//给当前节点赋值
    ListNode newHead=node;//给链表节点赋值
    for(int i=index-1;i>=0;i--){
        next=list.get(i);//给下一个节点赋值
        node.next=next;//给当前节点的内的下一个节点赋值
        node=node.next;//替换当前节点为下一个节点
    }
    node.next=null;//最后一个结点就是反转前的头结点,一定要让他的next等于空,否则会构成环
    return newHead;
}

执行用时:1 ms, 在所有 Java 提交中击败了8.32%的用户

内存消耗:38.3 MB, 在所有 Java 提交中击败了94.09%的用户

 

第二种利用双链表迭代方式,

public ListNode reverseList(ListNode head) { 
    ListNode newHead = null, next = null;//新链表
    while(head != null) {
        next = head.next;//下一个节点
        head.next = newHead;//每次访问的原链表节点都会成为新链表的头结点
        newHead = head;//更新新链表
        head = next;//重新赋值,继续访问
    }
    return newHead;
}

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:38.5 MB, 在所有 Java 提交中击败了75.06%的用户

 

第三种递归调用是要从当前节点的下一个结点开始递归。逻辑处理这块是要把当前节点挂到递归之后的链表的末尾

public ListNode reverseList3(ListNode head) {
    if (head == null || head.next == null)
    return head;
    ListNode next = head.next; //保存当前节点的下一个结点
    ListNode reverse = reverseList(next); //从当前节点的下一个结点开始递归调用
    next.next = head;  //reverse是反转之后的链表,head挂到next节点的后面就完成了链表的反转。
    head.next = null;//这里head相当于变成了尾结点,尾结点都是为空的,否则会构成环
    return reverse;
}

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:38.8 MB, 在所有 Java 提交中击败了34.76%的用户

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值