本来这只是一个普通的算法题,但是当初自己OJ上提交时,总是提交失败,而我自己认定程序逻辑没有任何问题。然后开始就在本机上调试,结果发现这是由于Python的对象机制而引发的。所以先把问题算法题贴出来,然后通过该问题,详述Python的对象机制!

题目描述:

输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

这道题本身不难,书上、网上也有很多关于该问题的解释,这里我就直接贴上我的Python代码(该代码有一处很隐晦的bug)。

 # -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回二维列表,内部每个列表表示找到的路径
def FindPath(self, root, expectNumber):
# write code here
if not root:
return [] ret = [] # 函数返回的二维列表
path = [] # 遍历过程中经历的路径,假如符合条件,就加入到ret列表中
self.Find(root, target, ret, path)
return ret def Find(self, root, target, ret, path):
if not root:
return path.append(root.val)
isLeaf = root.left is None and root.right is None
if isLeaf and target == root.val:
ret.append(path) # 对于叶子节点,加上符合条件的path. if root.left:
Find(root.left, target - root.val, ret, path)
if root.right:
Find(root.left, target - root.val, ret, path) path.pop()

算法程序逻辑没有任何问题,却总是通不过OJ。一遍遍审查后,实在找不出哪里的错误,然后尝试调试。

看到了吗?程序运行过程中,已经正确的把路径保存下来了。但是,最终程序返回的结果是包含两个[]的列表。

如此,突然感觉豁然开朗了,于是,把第27行换成 ret.append(path[:])

下面是改正后代码,成功通过OJ系统

# -*- coding:utf-8 -*-
class Solution:
# 返回二维列表,内部每个列表表示找到的路径
def FindPath(self, root, expectNumber):
# write code here
if not root:
return [] ret = []
path = []
self.Find(root, expectNumber, ret, path)
# print ret
# a = [];self.f(a);print a
return ret def Find(self, root, target, ret, path):
if not root:
return path.append(root.val)
isLeaf = (root.left is None and root.right is None)
if isLeaf and target == root.val:
ret.append(path[:]) # 这里这一步要千万注意啊,
# 假如是:ret.append(path), 结果是错的。因为Python可变对象都是引用传递啊。 #print "target:", target, "isLeaf:", isLeaf,
#print "val:", root.val, "path:", path, "ret:", ret
#print if root.left:
self.Find(root.left, target - root.val, ret, path)
if root.right:
self.Find(root.right, target - root.val, ret, path) path.pop()

至于为什么这小小的差别,会导致程序完全不同的运行行为,则涉及到Python的可变对象、不可变对象等机制。下一节,会对该问题进行详述!

剑指offer:二叉树中和为某一值的路径的更多相关文章

  1. 剑指offer 二叉树中和为某一个值的路径

    剑指offer 牛客网 二叉树中和为某一个值的路径 # -*- coding: utf-8 -*- """ Created on Tue Apr 9 15:53:58 2 ...

  2. 剑指Offer 二叉树中和为某一值的路径(dfs)

    题目描述 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.     思路: 递归,然后深搜,因为题目定义的, ...

  3. 剑指Offer——二叉树中和为某一值的路径

    题目描述: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 分析: 先序遍历二叉树,找到二叉树中结点值的和 ...

  4. 用java刷剑指offer(二叉树中和为某一值的路径)

    题目描述 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.(注意: 在返回值的list中,数组长度大 ...

  5. 用js刷剑指offer(二叉树中和为某一值的路径)

    题目描述 输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.(注意: 在返回值的list中,数组长度大 ...

  6. 剑指offer--31.二叉树中和为某一值的路径

    深度优先搜索 --------------------------------------------------------------------------------------------- ...

  7. 剑指Offer-24.二叉树中和为某一值的路径(C++/Java)

    题目: 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.(注意: 在返回值的list中,数组长度大的 ...

  8. 剑指offer-二叉树中和为某一值的路径

    题目描述 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.   解题思路 利用前序遍历的思想,定义FindP ...

  9. 剑指offer-二叉树中和为某一值的路径24

    题目描述 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.(注意: 在返回值的list中,数组长度大 ...

  10. 剑指offer-二叉树中和为某一值的路径-python

    题目描述 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.(注意: 在返回值的list中,数组长度大 ...

随机推荐

  1. 软件发布时的 GA、RC、Beta

    今天在使用 ovirt 的时候,遇到了其 Pre-release 版本并看到如下版本号:ovirt-node-ng-image-update-4.2.7-0.1.rc1.el7.noarch.rpm ...

  2. Python基础知识:模块

    目录 JSON模块&pickle模块 requests模块 time模块 datetime模块 logging模块 os模块 sys模块 hashlib模块 re模块.正则表达式 config ...

  3. D-Link DIR-600 - Authentication Bypass

    #Exploit Title: D-Link DIR-600 - Authentication Bypass (Absolute Path Traversal Attack) # CVE - http ...

  4. UGUI 文字效果实现(Shadow\Gradient\Outline)

    NGUI直接在UILabel组件中接入了Shadow.Gradient和outline选项,但在UGUI中是通过另外的组件单独提供,比如outline.shader等.这篇文章主要记录这几个文字效果实 ...

  5. WPFの数据源事件变更通知

    如果数据绑定的目标是TextBox元素的Text属性,那么默认会使用双向绑定(Mode.TwoWay),此时用户可以通过更改TextBox元素Text属性的值从而更新源属性信息,但是如果在程序代码中更 ...

  6. MATLAB——神经网络pureline激活函数

  7. js深度克隆对象

    js深度克隆对象 js深度克隆对象简单的记录一下,如下代码: var obj = { typeOf: function(obj) { const toString = Object.prototype ...

  8. MySQL 基础十一 事件

    1.查看事件 2.创建事件 3.执行事件,并查看执行结果是否正确 一 查看事件 -- 1.查看所有事件(显示执行频率(按年.月.日).创建日期.最后执行事件等)SELECT * FROM mysql. ...

  9. Android学习之基础知识十五 — 最佳UI体验(Material Design实战)

    一.前言 长久以来,大多数人都认为Android系统的UI并不美观,至少没有iOS系统的美观.以至于很多IT公司在进行应用界面设计的时候,为了保证双平台的统一性,强制要求Android端的界面风格必须 ...

  10. C语言中getch()、getche()和getchar()

    本文章为转载文章,文档贡献者wdzhangxiang 个人网址:www.baidu.com/p/wdzhangxiang 首先不要忘了,要用getch()必须引入头文件conio.h,以前学C语言的时 ...