LeetCode 第206题 反转链表 做题记录

题目描述

反转一个单链表
示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

我的解法

思路

最直接的想法是定义一个新的链表,对原链表进行遍历找到最后一个节点接到新链表后面,然后在原链表中删除该节点,直到原链表为空

编码过程中出现的问题

在这里插入图片描述
原因:在生成新链表时,每次循环都将原来的节点覆盖了
在这里插入图片描述
解决:新增了有关新链表的遍历操作
在这里插入图片描述

对应Java代码

在这里插入图片描述
时间复杂度O(n²)都能超过100%的用户吗。。。力扣的这个时间计算可能存在随机性

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode dummyNode = new ListNode(0,head);
        ListNode newNode = new ListNode(0);
        ListNode newCur = newNode;
        while (dummyNode.next != null) {
            ListNode cur = dummyNode;
            while (cur.next.next != null) {
                cur = cur.next;
            }
            newCur.next = cur.next;
            newCur = newCur.next;
            cur.next = cur.next.next; //删除原链表尾部结点
        }
        return newNode.next;
    }
}

复杂度分析

时间复杂度:O(n²)
空间复杂度:O(1)

更优解法

此部分转载于公众号代码随想录

思路

如果再定义一个新的链表,实现链表元素的反转,其实这是对内存空间的浪费。其实只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表,如图所示:
在这里插入图片描述

对应Java代码

在这里插入图片描述
运行时间上果然短了很多

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        while (cur !=null ) {
            ListNode tmp = cur.next; //保存cur的下一个节点用于后续遍历
            cur.next = pre; // 翻转操作
            // 更新pre 和 cur指针
            pre = cur; 
            cur = tmp;
        }
        return pre;
    }
}

复杂度分析

时间复杂度:O(n)
空间复杂度:O(1)

另一种方法

因为题目里提到有迭代和递归两种方法,现来记录下两者的区别

递归(recursion):递归常被用来描述以自相似方法重复事物的过程,在数学和计算机科学中,指的是在函数定义中使用函数自身的方法。(A调用A)
迭代(iteration):重复反馈过程的活动,每一次迭代的结果会作为下一次迭代的初始值。(A重复调用B)

上面使用的是迭代法,这里记录递归法,算法逻辑上是一样的,只是编码逻辑上不同

对应Java代码

class Solution {
    public ListNode reverse(ListNode pre,ListNode cur) { // 因为是递归,被调用的方法肯定要单独拿出来
        if(cur == null) { return pre; } // 函数体内定义递归的终止条件
        ListNode tmp = cur.next;
        cur.next = pre;
        return reverse(cur,tmp); // 递归
    }
    public ListNode reverseList(ListNode head) {
        // 递归前的初始化
        return reverse(null,head);
    }
}

收获总结

  1. 当你做的题思路混乱做了很多次才通过的时候,后面回想起来大概率还是会一片混乱的,好的方法肯定是逻辑清晰,且写法明确的。
  2. 那么有没有可以加深印象的方法呢?其实我觉得没有什么好的方法,最朴素的方法就是多做,每天都简单回顾下之前学到的方法,而且只是粗略的回想起算法的步骤轮廓是不够的,隔一段时间再上手做一遍;久而久之思维也会发生变化,看到题目后第一时间想到的就不会是暴力求解了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值