Reverse Singly LinkedList的方法探讨

今天在做LeetCode的一道Reverse Singly LinkedList题时,从discuss中汲取了不少经验,写文一篇做为总结和思考。

1.三个pointer迭代的常规方法



如图1所示,给出一个链表,现在我们要做的是把它翻转过来使得最终变为5->4->3->2->1的形式。最自然的想法是我们将每一个正在访问的结点(记为current)的next指针指到它的前一个结点(记为parent)。但是这样会有一个小问题,当current的next被重新赋值之后,current原本的下一个结点会丢失,所以我们还需要一个指针then来记录原链表中current的下一个结点。假设我们刚开始进行reverse的操作,第一个操作的结点是2,所有的记号如图2所示。






现在将current指向parent,结果如图3。从图中可以看到,有了then的存在,我们就可以找到下一个要访问的结点,继续往前遍历链表。
为了叙述简单,这里不考虑边界条件,给出该方法的主要循环体:

current.next = parent;
parent = current;
current = then;
then = then.next;

遇到边界条件,如head为空,链表长度不足3个等情况,处理起来也很容易。这里有一个链表中常用的技巧,就是使用一个不关心它存的值是多少的dummy node,把它放置在头结点的前面,这样可以省去关于头结点的边界条件判断。

2.头插法

此方法和建立链表时使用的头插法是一个意思,就是在一个链表的头部不断插入新的结点。在reverse完成后,原链表的头结点将成为新链表的尾部,因此我们把它记为tail。假设我们添加了一个dummy node在结点1的前面,那么头插法的运行过程如下:
访问继tail之后的第一个结点current,并把current拿出来,插入到链表的最前面(dummy node的后面),这样tail和current的位置就发生了交换。过程如图4所示。



然后,将current的值更新为此时tail所指向的下一个结点,再次重复该操作,直到末尾即可。这里给出完整的实现代码。

public ListNode reverseList(ListNode head) {
    if(head == null || head.next == null) return head;
    
    ListNode dummy = new ListNode(0);
    dummy.next = head;
    ListNode tail = dummy.next;
    ListNode cur = tail.next;
    while(cur != null) {
        tail.next = cur.next;
        cur.next = dummy.next;
        dummy.next = cur;
        cur = tail.next;
    }
    return dummy.next;
}

相比于第一个方法,个人觉得这种方法比较容易操作,需要考虑的东西比较少,当然第一个方法是最容易想到的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值