zoukankan      html  css  js  c++  java
  • 206.反转链表

     <循环不变式的思想>

    题目描述


    反转一个单链表。

    示例:

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

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

     

    我的思路  - 迭代


    class Solution:
        def reverseList(self, head: ListNode) -> ListNode:
            pre = None
            while head:
                t= head.next
                head.next = pre
                pre = head
                head = t
            return pre
    • 算法: 

    1. 遍历head结点,用 pre 标记 head 之前的结点,用 t 标记 head 之后的结点。

    2. head 结点 指向 pre 结点
    3. 继续下一个循环

    我的思路 - 递归(误)


    class Solution:
        def reverseList(self, head: ListNode) -> ListNode:
            if not head.next:
                return head
            ans = self.reverseList(head.next)
            # 回溯的时候head从5回到1,这时用ans来指向它(误)
            ans.next = head 
            return ans
    • 算法:

    1. 递归到底,返回尾结点
    2. 回溯的时候用ans指向当前栈帧的结点
    • 存在的问题:

      • 回溯的时候反转结点,这个思路可能导致最后return的是反转后的链表的尾结点(这里return ans就不会出现这个问题了)
      • 最致命的一点:ans是递归到底得到的结果,回溯的时候把 ans 递给上一层,所以 ans 在这里是不会变的。那么什么时候会导致return的结果变化呢?参考这篇文章

         

     题解 - 递归


    class Solution(object):
        def reverseList(self, head):
            if not head.next:
                return head
            ans = self.reverseList(head.next)
            # 回溯的时候当前栈帧的结点是head,我们把head的下一个结点指向当前的head
            head.next.next = head
            head.next = None
            return ans
    •  算法:

      • 结合上面【我的思路】来看

    总结


    • 如何用循环不变式来思考?

      • 考虑初始状态:比如设置虚拟头节点、确定第一次循环从哪个结点开始、等等
      • 考虑保持状态(循环中):我们假设循环到结点P,且P之前的结点已经达到目的,专注于当前结点P该用什么样的算法。
      • 考虑终止状态:主要是防止越界。。
  • 相关阅读:
    兼容火狐几秒后跳转页面
    js 利用sina ip库获取ip及通信服务商
    jQuery.validate 中文API
    s:select标签的Map形式使用
    【原创随笔】reCAPTCHA加密验证Email地址,正确才可完整查看地址!
    eclipse编辑jsp文件和javascript代码很卡解决办法
    oracle 10 R2 静默安装 + psu
    【容易成功的十种能力你具备几种
    CentOS 新虚拟机网卡设置
    【与人沟通的技巧很重要】
  • 原文地址:https://www.cnblogs.com/remly/p/11406425.html
Copyright © 2011-2022 走看看