【leedcode.206】反转链表递归和非递归举例详解

递归

# 经典的代码贴上

def reverse_list(self, head):

    if not head or not head.next:  # not head 是为了防止空列表;

        return head

    newH = self.reverse_list(head.next) # 一直为5,因为是新链表表头

    head.next.next = head

    head.next = None  # 因为是递归,只执行了5->4操作,但是这时候4仍然指向5,所以需要去掉这个指向;在从前往后的迭代中,类似操作是cur = cur.next

    return newH

理解:

    拿题目举例,[1->2->3->4->5]     ->   [5->4->3->2->1]

    1.递归到head=4时,self.reverse_list得到newH为5;

    2.head.next.next = head,(一个next表示指向下一个)所以实质上是5->4;  

    3.head.next = None表示断开原来4指向5的箭头(4—>None);

    4.依次循环,但每一次都是返回的都是新链表的头5,所以返回的值都是newH;

 

非递归

# 同样经典代码贴上

def reverse_list(self, head):
    # 题目说了是反转链表的头结点,所以不能再建一个dummy
    # dummy = ListNode(None)
    # dummy.next = head

    cur, pre = head, None

    while cur:

        cur.next, pre, cur = pre, cur, cur.next

    return prex

理解:

    同样对于None->1->2->3->4->5

    1.pre指向None, cur指向1

    2.cur下移一位指向2(cur.next),pre同样下移一位指向1(cur),再让2(cur.next)指向1(pre)

 

    只是上面经典代码是利用的python多变量赋值才能这么简洁,如果分开写要注意两点:

        1)、(cur.next)指向(pre)要在cur(当前指向1)下移一位指向cur.next(指向2) 之后; 因为如果先让(cur.next)指向(pre),这样先刷新了cur.next值,导致指针再无法取后面的值了

        2)、2(cur.next)指向1(pre)这一步要发生在pre下移一位指向1(cur)之后,否则如果是下面的顺序:

            cur = cur.next(cur指针由1移到2)

            cur.next = pre (2->None即2的下一个是None)

            pre = cur  (pre指针移到1)

            最终是None->1->2->None,形成了环

 

           不用python的多变量赋值代码:

            a = cur.next

            cur.next = pre

            pre = cur  

            cur = a 

           

ps:

python的多变量赋值:

【leedcode.206】反转链表递归和非递归举例详解_第1张图片

如上图,3个变量同时赋值时,虽然cur进行了更新,但是pre拿到的是cur更新前的值;cur_next也是拿的pre更新前的值;可见python多变量赋值涉及同一变量传值与更新时,往往先传值后更新;并且python变量赋值是指新变量指向原变量的指针对象,与原变量更新无影响

你可能感兴趣的:(leedcode,Linked,List)