LeetCode206.反转链表

题目:

https://leetcode-cn.com/problems/reverse-linked-list/

 

题解一:

迭代+头插法。开辟一条新链表,遍历旧链表,逐个插入到新链表的头部。时间复杂度:O(n)。

    public ListNode reverseList(ListNode head) {
        // 哨兵节点
        ListNode node = new ListNode();
        while (head != null) {
            ListNode newNode = new ListNode(head.val);
            newNode.next = node.next;
            node.next = newNode;
            head = head.next;

        }

        return node.next;
    }

该方法核心在于头插法的使用,逻辑简单,但是每次都需要开辟新的结点,浪费空间。

 

题解二:

双指针法。一个指针指向当前结点 current,一个指针指向前结点前一结点 pre,两个指针同时向后遍历,并修改指针指向。时间复杂度:O(n)。

    public ListNode reverseList(ListNode head) {
        // 临时结点
        ListNode temp;
        // 前结点
        ListNode pre = null;
        // 当前结点
        ListNode current = head;
        while (current != null) {
            // 先保存当前结点的next
            temp = current.next;
            // 改变指针指向
            current.next = pre;
            
            // 移动指针
            pre = current;
            current = temp;
        }

        return pre;
    }

注意:

1.在改变指针指向之前需要保存当前结点的next指向。

2.遍历结束后,current 指向 null,pre 指向的就是原链表最后一个结点,也就是翻转后新链表的第一个结点。

 

题解三:

双指针+递归。用递归实现双指针解法,时间复杂度:O(n)。

    public ListNode reverseList(ListNode head) {
        // pre = null, current = head
        return reverse(null, head);
    }

    public ListNode reverse(ListNode pre, ListNode current) {
        // 递归边界
        if (current == null) {
            return pre;
        }

        // 保存当前结点的next
        ListNode temp = current.next;
        // 改变指针指向
        current.next = pre;

        // 移动指针并递归
        return reverse(current, temp);
    }

思想和题解二一样,移动指针的同时改变指针指向,当 current 指向 null 时表示已经遍历到链表末尾,应该结束递归,返回头结点。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值