反转链表
输入一个链表,反转链表后,输出新链表的表头。
笔记:看到第一思路是用list做,结果一直出错,看了高分回答不太理解,找了资料,直到找到最详细的图解博客,感谢大神~
https://blog.csdn.net/feliciafay/article/details/6841115
https://blog.csdn.net/The__Apollo/article/details/78769400
如何把一个单链表进行反转?
方法1:将单链表储存为数组,然后按照数组的索引逆序进行反转。
方法2:使用3个指针遍历单链表,逐个链接点进行反转。
方法3:从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。
方法4: 递归(相信我们都熟悉的一点是,对于树的大部分问题,基本可以考虑用递归来解决。但是我们不太熟悉的一点是,对于单链表的一些问题,也可以使用递归。可以认为单链表是一颗永远只有左(右)子树的树,因此可以考虑用递归来解决。或者说,因为单链表本身的结构也有自相似的特点,所以可以考虑用递归来解决)
方法1:浪费空间
是比较容易想到的,但是总是出错,目前都没找到原因,代码先放在这里,后面熟练了再改改看~
错误的代码
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
l = []
while pHead != None:
l.append(pHead)
pHead = pHead.next
res = {}
i = len[l] -1
while i>= 0:
res{l[i]} = i
i -= 1
return res
方法2:3个指针遍历单链表,感谢大神的详细讲解
使用p和q两个指针配合工作,使得两个节点间的指向反向,同时用r记录剩下的链表。
p = head;
q = head->next;
head->next = NULL;
现在进入循环体,这是第一次循环。
r = q->next;
q->next = p;
p = q;
q =r;
第二次循环。
r = q->next
q->next = p;
p = q;
q = r
第三次循环。。。。。
Python代码:
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
# write code here
if not pHead or not pHead.next:
return pHead
last = None
while pHead:
tmp = pHead.next
pHead.next = last
last = pHead
pHead = tmp
return last
**方法三:**比较好容易理解所有不加上图了,但是代码自己用python还是写不出来,倒了一下,能读懂代码,菜是原罪呀~
代码如下:p一直向后移动,直到末尾~
def func2(head):
p = head.next
while p.next:
q = p.next
p.next = q.next
head.next = q
q.next = p
p.next = head #形成环形
head = head.next
p.next.next = None #断开连接
return head
方法4:递归
发现大部分问题都可以从递归角度想想,所以这道题目也从递归角度想了想。
现在需要把A->B->C->D进行反转,
可以先假设B->C->D已经反转好,已经成为了D->C->B,那么接下来要做的事情就是将D->C->B看成一个整体,让这个整体的next指向A,所以问题转化了反转B->C->D。那么,
可以先假设C->D已经反转好,已经成为了D->C,那么接下来要做的事情就是将D->C看成一个整体,让这个整体的next指向B,所以问题转化了反转C->D。那么,
可以先假设D(其实是D->NULL)已经反转好,已经成为了D(其实是head->D),那么接下来要做的事情就是将D(其实是head->D)看成一个整体,让这个整体的next指向C,所以问题转化了反转D。
上面这个过程就是递归的过程,这其中最麻烦的问题是,如果保留新链表的head指针呢?想到了两个办法。
/ 递归版的第一种实现,借助类的成员变量m_phead来表示新链表的头指针。
第二个办法是,增加一个引用型参数 new_head,它用来保存新链表的头指针。
笔记:有些没怎么看懂的,记下来后面继续看~
def func3(head):
if head.next == None:
return head
new_head = func3(head.next)
head.next.next = head
head.next = None
return new_head