Python程序员面试算法宝典---解题总结: 第三章 二叉树 3.10 如何在二叉树中找出与输入整数相等的所有路径

# -*- coding: utf-8 -*-

'''
Python程序员面试算法宝典---解题总结: 第三章 二叉树 3.10 如何在二叉树中找出与输入整数相等的所有路径

题目:
从树的根节点开始往下访问一直到叶子结点经过的所有节点形成一条路径。找出所有的
这些路径,使其满足这条路径上所有结点数据的和等于给定的整数。例如:
给定如下二叉树与整数8,满足条件的路径为: 6->3->-1.
                                6
                3                            7
        9               -1              1       -5
    -10     2

分析:
所求的是从根节点到叶子的路径
判断叶子节点就是无左右节点。
我们可以用这样的方式来做。
以根结点6为例,如果要求和为8, 那么除了根结点6外,它的
左孩子为根结点或者右孩子为根结点的路径和必须是: 8 - 6 = 2
继续向下寻找,一旦找到某个结点符合期望的值,并且为叶子节点,
则说明找到这条路径。注意回溯。

还有一个问题,这里要找到所有路径,需要每次找到路径后都保存起来,
这个需要用栈来做。

关键:
1 书上解法
采用回溯法来做。回溯法的结构是:
步骤:1 对当前数据进行操作(例如压入到数组)
判断当前数据和其他条件是否满足结果,如果满足结果,则打印结果
步骤2:2 递归处理
步骤3: 清除步骤1中对当前数据的处理(例如从数组中删除数据)

2 针对这道题
可以每次将当前数据累加到和中,看和是否等于所要求的的 结果
参考:
Python程序员面试算法宝典
'''

class BinaryTreeNode(object):

    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right


def buildTree(data):
    if not data:
        return
    nodes = list()
    for value in data:
        node = BinaryTreeNode(value)
        nodes.append(node)
    size = len(data)
    for i in range(size / 2):
        if not nodes[i]:
            continue
        if 2 * i + 1 < size:
            nodes[i].left = nodes[2 * i + 1]
        if 2 * i + 2 < size:
            nodes[i].right = nodes[2 * i + 2]
    return nodes[0]


'''
                                6
                3                            7
        9               -1              1       -5
    -10     2

'''
class Stack(object):

    def __init__(self):
        self.data = list()

    def empty(self):
        result = False if self.data else True
        return result

    def push(self, data):
        self.data.append(data)

    def pop(self):
        if self.empty():
            info = "stack is empty, it can not pop"
            print info
        else:
            self.data.pop()

    def top(self):
        if self.empty():
            info = "stack is empty, it can not get top element"
            print info
        else:
            return self.data[-1]


class MyTree(object):
    def __init__(self, findValue):
        self.results = list()
        self.findValue = findValue
        self.stack = Stack()

    # def find(self, root, findValue):
    #     if not root:
    #         return 0
    #     self.stack.push(root)
    #     leftValue = self.find(root.left, findValue - root.data)
    #     rightValue = self.find(root.right, findValue - root.data)
    #
    #     # 判断当前节点是否是叶子节点,如果是叶子节点,可以判断findValue 如果等于root.data,就说明
    #     # 找到这样的一条路径,此时就应该讲路径保存起来
    #     if root.left is None and root.right is None:
    #         if leftValue + root.data == findValue:
    #             self.stack.push(root)
    #             self.results.append(self.stack)
    #     else:
    #         # 说明这个是非叶子节点,继续递归处理
    #         self.stack.pop(root)
    #         return root.data


def find(root, sums, findValue, results):
    if not root:
        return
    sums += root.data
    results.append(root.data)
    # 如果当前节点是叶子节点并且符合条件,说明找到这条路径,则打印路径
    if root.left is None and root.right is None and sums == findValue:
        info = ""
        for value in results:
            if info:
                info += "," + str(value)
            else:
                info += str(value)
        print info
    # 递归处理
    find(root.left, sums, findValue, results)
    find(root.right, sums, findValue, results)

    # 回溯,将之前压入的数据清除
    sums -= root.data
    results.remove(root.data)


def process():
    data = [6, 3, 7, 9, -1, 1, -5, -10, 2]
    root = buildTree(data)
    findValue = 8
    sums = 0
    results = list()
    find(root, sums, findValue, results)


if __name__ == "__main__":
    process()

猜你喜欢

转载自blog.csdn.net/qingyuanluofeng/article/details/91947682