Python中的BST序列

#开始背景

几年前,我踏上了认真学习编程领域的旅程,并且开始编写有关Codecademy的教程以及注册有关Udemy的课程。 由于我的工作涉及很多旅行,因此我将教程离线下载到ipad中,然后在飞机上进行了研究。 我最初的目的是学习编程以构建有用的东西,尽管旅途非常艰难,但我意识到,直到我将自己浸入数据结构和算法之前,我才知道“困难”一词的真正含义。

我是航空工程专业,毕业于新加坡头等舱荣誉。 之后,我以新产品工程师的身份加入斯伦贝谢,从事油田泵的工作,并曾在北海安装设备。 工作时间很长(每天工作16小时,周末通常也很花时间),薪水很低,但体验却很棒,我不会用它来换其他任何东西。 直到今天,进行翻船演习,降落挪威逃生滑道以及将直升飞机带到钻机的生存训练都是美好的回忆,除非他们是油田工程师,否则他们不会经历到这些。

之后,我加入宝洁,担任护发品牌研究人员,经过两次晋升后,我开始意识到,尽管项目管理,利益相关者管理(确保与您合作的每个人都满意)和树立信誉可能很重要,但实际上最重要的地方是,我没有获得做我热衷于做的事情所需的技能,即构想,制造有用的东西来解决问题并建立品牌。 不过,我所浸入的环境很棒,在同事和管理人员的支持下。 在这样的公司环境中工作使我意识到要了解公司的运作方式还有很多。 管理层如何做出决策(无论是基于数据还是基于直觉(这就是为什么企业是一门如此美丽的科学,同时也是一门艺术),这是关于分配人员和资源以及整合不同部门为打造和振兴品牌所做的努力的决策。 很棒的东西。

我想通过提供快速而准确的事实来帮助公司各级管理层和产品经理做出更明智的决策,这促使我开始编程,为大众创建了一个抓取和数据挖掘工具,该工具具有一直为致力于Pantene,Vicks,Tide,Head and Shoulders,SKII,Oral b等数十亿美元品牌的团队提供有价值的消费者见解。该工具称为www.wheregottext.com (缩写为WGT)(我已经建立了身份验证因此只有宝洁员工才能创建帐户)。

除了WGT之外,我还开发了一个求职应用程序和一个用于识别超市中产品的应用程序,并显示了其他消费者的相关在线评分和评论,以便消费者可以在购买前做出更明智的决定,而不仅仅是与销售人员交谈。商店的代表等。 我还参与了Android和iOS应用程序的开发,我将在下一次介绍。

无论如何,只要有足够的怨言,我将在另一篇文章中留下更多介绍。 到现在为止,我遇到的最困难的问题之一是这个问题:给定一个BST,找到可以制作BST的列表清单。

#结束背景

我将使用Gayle Laakmann McDowell的《破解编码面试》中的示例来提供我的观点和解释,希望遇到这个问题的人不会像我尝试在网上找到有用的解释时那样挣扎,但没有成功。 我将提供Python中的代码。 本书中的代码是用Java编写的。

考虑左边的二叉搜索树。 我们可以尝试手动列出一些可能的数组,其中包含可以插入以形成二进制搜索树的元素。

[20,10,5,15,25]

[20,10,25,5,15]

[20,25,10,15,5]

注意,对于每个子树(由三个节点组成),必须始终先插入根,然后再按子级的任何顺序插入子级,因为子级处于同一级别。

我最初解决这个问题的方法是首先对所有节点进行遍历,然后将节点存储到列表中。 然后,我将生成元素的所有排列的列表的列表,此后过滤掉以值20开头的列表,以及条件10出现在5和15之前的条件(因为必须先添加10以形成BST)。 这种想法有很多缺陷。 这是一种非常手动的方法,如果BST较大,或者如果我们无法在上面的图表中可视化BST,则计算节点的层次结构将不必要地变得复杂。 我们可以做一个BFS并弄清楚10必须在5和15之前,但是我宁愿遵循课本方法而不是实现它。

我们知道,我们总是将问题分解为较小的问题,然后对于BST,我们可以使用回溯将解决方案扩展到更大的问题。 在这本书中,使用了两个递归函数。 一个称为weaveLists,另一个称为allSequences,它称为weaveLists。

首先,让我们定义一个Tree类。 我们需要能够插入并获得根。

class Node:
def __init__(self, val):
self.l = None
self.r = None
self.v = val
class Tree:
def __init__(self):
self.root = None
def getRoot(self):
return self.root
def insert(self, val):
if(self.root == None):
self.root = Node(val)
else:
self._insert(val, self.root)
def _insert(self, val, node):
if(val < node.v):
if(node.l != None):
self._insert(val, node.l)
else:
node.l = Node(val)
else:
if(node.r != None):
self._insert(val, node.r)
else:
node.r = Node(val)

此后,我们希望能够编织子树的元素。 weaveList函数如下(我将注释直接添加到代码中以解释发生了什么):

#注意,在递归中,我们始终对第一,第二和前缀列表使用相同的引用,因此修改这些列表的操作必须就地完成。 任何副本都必须使用Deepcopy功能完成。

###编辑以下代码:而不是使用result = prefix.copy(),请使用:

import copy
result = copy.deepcopy(prefix)

由于.copy()是浅表副本。

谢谢智勇指出。

# 'first' list shall be referred to as first[]
# 'second' list shall be referred to as second[]
# 'prefix' list shall be referred to as prefix[]
def weaveLists(first, second, results, prefix):
# if first or second is an empty list
if not first or not second:
# ensuring that result is a CLONE and not a reference to prefix
result = prefix.copy() ### EDIT HERE TO DEEPCOPY
# add result to first or/ and second lists
if first:
result += first
if second:
result += second
# append the weaved list which is result, to results
results.append(result)
return
        # add result to first or/ and second lists
if first:
result += first
if second:
result += second
# append the weaved list which is result, to results
results.append(result)
return
    # this would be the method as described in the textbook
# first, remove and store first element of first[]
headFirst = first.pop(0)
# append to prefix
prefix.append(headFirst)
### add recursive call to operate on first[]
weaveLists(first, second, results, prefix)
# exit when first[] is empty
    # reset prefix for second recursive call below by removing last element
# IMPT to modify in-place
del prefix[-1]
# reset first[] for second recursive call below by adding back first element
# IMPT to modify in-place
first.insert(0,headFirst)
    # do the same thing on the second[]
headSecond = second.pop(0)
prefix.append(headSecond)
### add recursive call to operate on first[] and second[]
weaveLists(first, second, results, prefix)
del prefix[-1]
second.insert(0,headSecond)

我们希望weaveList函数在子树上运行并构建到整个Tree。

因此,通常,我们希望weaveList在蓝色的子树1上工作,然后在绿色的整个树上工作。

因此,allSequences的代码为(带有注释以供解释):

def allSequences(node):
# this is the final list of lists we want to output
results = []
# termination, append [] so that results will not be empty\
# and the nested for loop will still execute since
# leftSeq == [[]] and rightSeq == [[]] in termination
if not node:
results.append([])
return results
    # prefix will always be root of subtree
prefix = []
prefix.append(node.v)
# then represent the left and right subtrees
leftSeq = allSequences(node.l)
rightSeq = allSequences(node.r)
    # nested for loop and call weaveLists on each list in
# leftSeq and rightSeq, which are list of lists
# and each represents results of each subtree
for left in leftSeq:
for right in rightSeq:
# make weaved an empty list,
# which is results in weaveList
weaved = []
weaveLists(left, right, weaved, prefix)
# weaved is list of lists generated by left[] and right[]
# add weaved list of lists to final
# results list of lists
results += weaved
return results

驱动程序的主要功能是:

if __name__ == "__main__":
    tree = Tree()

tree.insert(20)
tree.insert(10)
tree.insert(25)
tree.insert(5)
tree.insert(15)
    allSeq = allSequences(tree.getRoot())
    for each in allSeq:
print (each)
print (len(allSeq))

将所有代码复制到一个脚本中并运行以查看结果。 该代码在Python3中。

如有任何意见,建议或问题,请随时与我们联系。

From: https://hackernoon.com/bst-sequences-in-python-c072c0e9b19f

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值