从尾到头打印链表
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
思路
- 解法1
栈结构存储数据。正向遍历,将node.val压栈,利用栈先进后出的特点,返回ArrayList。 - 解法2
链表结构反向。创建三个指针cur,pre,temp。遍历链表时,pre为cur的前驱节点,temp保存cur的后继节点后,修改cur的后继节点为pre。遍历结束时,cur指向空,pre指向尾节点。从尾节点开始遍历,返回链表值即可。 - 解法3
递归思想求解。将问题化简为更小的问题。每次调用函数时,在ArrayList的尾端添加node.val,head节点在ArrayList[-1]添加元素,head.next在ArrayList[:1][-1]中添加元素。递归的出口是None,此时创建空的ArrayList。
注意:Python中list的append方法没有返回值,因此采用“+”这种组合列表的方法。
代码
# -*- coding: utf-8 -*-
class ListNode:
def __init__(self,x):
self.val = x
self.next = None
class Solution:
def printListFromTailToHead1(self,listNode): #利用栈的先进后出
temp,res = [],[] #额外空间复杂度O(n)
while listNode:
temp.append(listNode.val) #temp中存储正向链表值
listNode = listNode.next
while temp:
res.append(temp.pop()) #res中存储反向链表值
return res
def printListFromTailToHead2(self,listNode): #反转链表指针
res = [] #额外空间复杂度O(1)
cur,pre = listNode,None
while cur:
temp = cur.next
cur.next = pre
pre = cur
cur = temp #循环结束时,链表反向,pre指向尾节点
while pre:
res.append(pre.val)
pre = pre.next
return res
def printListFromTailToHead3(self,listNode): #方法1的递归版本
if not listNode:
return []
return self.printListFromTailToHead3(listNode.next)+[listNode.val] #用+代替append
def printListFromTailToHead4(self,listNode): #方法1的错误递归版本
if not listNode:
return []
return self.printListFromTailToHead4(listNode.next).append(listNode.val) #a.append(1)无返回值
if __name__ == "__main__":
listNode = ListNode(1)
listNode.next = ListNode(2)
listNode.next.next = ListNode(3)
solution = Solution()
print solution.printListFromTailToHead4(listNode)
重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
注意: 输入前序和后序的数据类型是List,输出返回类型为Node
思路
递归思想求解。考虑到二叉树根节点的lchild和rchild也是二叉树,将问题化简成更小的问题。每次递归中,前序中的首节点为树的根节点root,在中序序列中,root的左边是root.lchild,root的右边是root.rchild。而root.lchild是左子树的根节点,处理方法相同。递归函数的出口是,前序数组长度为1(此时中序数组也为1),创建叶节点并返回。
特殊情况,前序数组长度为1,说明没有左子树或右子树,返回None。
代码
# -*- coding: utf-8 -*-
class TreeNode:
def __init__(self,x):
self.val = x
self.left = None
self.right = None
def preOrderRec(self,x): #测试函数
if x is None:
return
print x.val,
self.preOrderRec(x.left)
self.preOrderRec(x.right)
class Solution:
def reConstructBinaryTree(self,pre,tin): #递归实现二叉树重建
if len(pre) == 0: #没有子树
return None
elif len(pre) == 1: #pre[0]对应叶节点
return TreeNode(pre[0])
else:
root = TreeNode(pre[0])
rootIndex = tin.index(pre[0])
root.left = self.reConstructBinaryTree(pre[1:rootIndex+1],tin[:rootIndex+1]) #中序中,根节点左侧为左子树
root.right = self.reConstructBinaryTree(pre[rootIndex+1:],tin[rootIndex+1:]) #中序中,根节点右侧为右子树
return root
if __name__ == "__main__":
pre = [1,2,4,7,3,5,6,8]
tin = [4,7,2,1,5,3,8,6]
solution = Solution()
root = solution.reConstructBinaryTree(pre,tin)
root.preOrderRec(root)