从尾到头打印链表
题目: 输入一个链表,返回一个反序的链表。
比如:1---->2---->3----->4 4----->3----->2----->1
这其实是先进后出啊,这是栈的基本形式。每经过一个节点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始逐个输出结点的值,给一个新的链表结构,这样链表就实现了反转。
class Node(object):
def __init__(self, dataval):
self.dataval = dataval
self.nextval = None
class reverse(object):
def __init__(self):
self.headval = None
#创建链表
def append(self,newdata):
#将数据转化为节点
Newnode = Node(newdata)
if self.headval ==None:
self.headval = Newnode
else:
laste = self.headval
while laste.nextval:
laste = laste.nextval
laste.nextval = Newnode # 注意
#将数据存入链表
def save_list(self):
printval = self.headval
#创建一个列表
s_list = []
while printval:
# print(printval.dataval)
s_list.append(printval.dataval)
printval = printval.nextval
return s_list
def size(self):
return len(self.save_list())
def run_reserve(self):
list = self.save_list()
length = self.size()
self.headval = Node(list[-1])
for i in range(length-1):
self.append(list[length-2-i])
def show(self):
printval = self.headval
while printval:
print(printval.dataval)
printval = printval.nextval
if __name__ == '__main__':
li = reverse()
e1 = li.append('1')
e2 = li.append('2')
e3 = li.append('3')
e4 = li.append('4')
list = li.save_list()
run_reserve = li.run_reserve()
li.show()
###结果
4
3
2
1
[Finished in 0.2s]
链表中倒数第K个节点
题目:输入一个链表,输出该链表中倒数第k个结点。
步骤:
- 创建链表
- 求出链表长度L
- 倒数第k个节点就是正数第(L-k)个节点
代码:
class Node(object):
def __init__(self, dataval):
self.dataval = dataval
self.nextval = None
class ListNode(object):
def __init__(self):
self.headval = None
#创建链表
def append(self,newdata):
#将数据转化为节点
Newnode = Node(newdata)
if self.headval ==None:
self.headval = Newnode
else:
laste = self.headval
while laste.nextval:
laste = laste.nextval
laste.nextval = Newnode # 注意
#将数据存入链表
def save_list(self):
printval = self.headval
#创建一个列表
s_list = []
while printval:
# print(printval.dataval)
s_list.append(printval.dataval)
printval = printval.nextval
return s_list
#链表长度
def size(self):
return len(self.save_list())
#打印倒数第k个节点
def print_k(self,k):
list = self.save_list()
length = self.size()
return list[length-k]
# def run_reserve(self):
# list = self.save_list()
# length = self.size()
# self.headval = Node(list[-1])
# for i in range(length-1):
# self.append(list[length-2-i])
# def show(self):
# printval = self.headval
# while printval:
# print(printval.dataval)
# printval = printval.nextval
if __name__ == '__main__':
li = ListNode()
e1 = li.append('1')
e2 = li.append('2')
e3 = li.append('3')
e4 = li.append('4')
print_k = li.print_k(3)
print(print_k)
# list = li.save_list()
# run_reserve = li.run_reserve()
# li.show()
# print(list)
####结果
2
[Finished in 0.3s]
反转链表
这已经实现了,请看从尾到头打印链表。
合并两个排序的链表
题目:输入两个单调递增的链表,输出两个链表合成后的链表,合成之后的链表满足单调不减原则。
方法一
- 把这两个链表放入数组中
- 合并数组形成新的数组
- 对数组排序(从小到大)----可以选择分而治之,也就是递归算法
- 把排序后的数组,按从左到右的顺序,创建新的链表
方法二
递归方法
参考文献:
简答讲解递归:“递”+“归”
与循环的区别
递归是静中有动,有去有回。
循环是动静如一,有去无回。
递归:你打开面前这扇门,看到屋里面还有一扇门(这门可能跟前面打开的门一样大小(静),也可能门小了些(动)),你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,你继续打开,。。。, 若干次之后,你打开面前一扇门,发现只有一间屋子,没有门了。 你开始原路返回,每走回一间屋子,你数一次,走到入口的时候,你可以回答出你到底用这钥匙开了几扇门。
循环:你打开面前这扇门,看到屋里面还有一扇门,(这门可能跟前面打开的门一样大小(静),也可能门小了些(动)),你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,(前面门如果一样,这门也是一样,第二扇门如果相比第一扇门变小了,这扇门也比第二扇门变小了(动静如一,要么没有变化,要么同样的变化)),你继续打开这扇门,。。。,一直这样走下去。 入口处的人始终等不到你回去告诉他答案。
递归思想
递归就是有去(递去)有回(归来)。
具体来说,为什么可以”有去“?
这要求递归的问题需要是可以用同样的解题思路来回答类似但略有不同的问题(上面例子中的那一把钥匙可以开后面门上的锁)。
为什么可以”有回“?
这要求这些问题不断从大到小,从近及远的过程中,会有一个终点,一个临界点,一个baseline,一个你到了那个点就不用再往更小,更远的地方走下去的点,然后从那个点开始,原路返回到原点。
两个链表都是排序好的,我们只需要从头遍历链表,判断当前指针,哪个链表中的值小,即赋给合并链表指针即可。
- 可以有回,找到临界点。先判断输入的链表是否为空的指针。如果第一个链表为空,则直接返回第二个链表;如果第二个链表为空,则直接返回第一个链表。如果两个链表都是空链表,合并的结果是得到一个空链表。
- 有去。找到那把“钥匙”。
class Node(object):
def __init__(self, dataval):
self.dataval = dataval
self.nextval = None
class Solution(object):
def __init__(self):
self.headval = None
self.new_head = None
def combine(self,first_headval,second_headval):
#先有临界条件
if first_headval == None:
return second_headval
if second_headval == None:
return first_headval
#有去
self.new_head = None
if first_headval.dataval<second_headval.dataval:
self.new_head = first_headval
self.new_head.nextval = self.combine(second_headval,first_headval.nextval)
else:
self.new_head = second_headval
self.new_head.nextval = self.combine(first_headval,second_headval.nextval)
def show(self):
printval = self.new_head
while printval:
print(printval.dataval)
printval = printval.nextval
复杂链表的复制
题目:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
算法:
- 从头读复杂链表,找到每个节点的指针指向。
- 新建链表,节点关系(指针指向)是复杂链表原有的节点关系
可以用迭代的思路:
- 临界点,节点的指向下一个节点的指针指向了none
- 迭代的算法,复制每一个节点的节点关系
class Node(object):
def __init__(self, dataval):
self.dataval = dataval
self.nextval = None
self.randval = None
class Solution(object):
def __init__(self):
# self.headval = None
self.new_head = None
#开始复制
def reread(self,oragin_head):
#临界点
if not oragin_head:
return None
self.new_head = Node(oragin_head.dataval)
laste = self.new_head
laste.randval = oragin_head.randval
laste.nextval = self.reread(oragin_head.nextval)
return self.new_head
两个链表中的第一个公共节点
题目:输入两个链表,找出它们的第一个公共节点
- 第一个链表的第一个节点与第二个链表的所有节点比较
- 然后第一个链表的第二个节点与第二个链表的所有节点比较
- …
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
# write code here
if pHead1 is None or pHead2 is None:
return None
pHead3 = pHead2
while pHead1:
while pHead2:
if pHead2 == pHead1:
return pHead2
pHead2 = pHead2.next
pHead2 = pHead3 # 这个地方容易出错,真的容易出错
pHead1 = pHead1.next
return None
链表中环的入口节点
题目:一个链表中包含环,请找出该链表的环的入口结点。
- 从头读取链表中的数据并记录在新建的数组中
- 每读取一个数据,就与数组中的数据比较是否有一样的元素。如果有,那这个元素就是环的入口。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
if pHead == None:
return None
printval = pHead
new_list = []
while printval:
new_list.append(printval.val)
if new_list.count(new_list[-1]) == 2:
return ListNode(new_list[-1])
else:
printval = printval.next
return None
删除链表中重复的节点
题目:
在一个排序的链表中,存在重复的节点,请删除该链表中重复的节点,重复的节点不保留,返回链表头指针。例如:链表1->2->3->3->4->4->5 处理后为 1->2->5。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteDuplication(self, pHead):
# write code here
if pHead == None:
return None
printval = pHead
temp = []
while printval:
temp.append(printval.val)
printval = printval.next
res = ListNode(None)
head = res
for i in temp:
if temp.count(i) == 1:
head.next = ListNode(i)
head = head.next
#new_head = new_head.next
return res.next
那么剑指offer之链表部分已经上述了一遍。如果大家有什么疑问,可以随时问。