C#刷剑指Offer | 二叉树中和为某一值的路径

【C#刷题作者 / Edison Zhou

这是EdisonTalk的第292篇原创内容


我们来用之前学到的数据结构知识来刷《剑指Offer》的一些核心题目(精选了其中30+道题目),希望对你有帮助!本文题目为:二叉树中和为某一值的路径。

1题目介绍

题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。例如输入下图中二叉树和整数22,则打印出两条路径,第一条路径包含结点10、12,第二条路径包含结点10、5和7。

二叉树结点的自定义代码如下:

public class BinaryTreeNode
{public int Data { get; set; }public BinaryTreeNode leftChild { get; set; }public BinaryTreeNode rightChild { get; set; }public BinaryTreeNode(int data){this.Data = data;}public BinaryTreeNode(int data, BinaryTreeNode left, BinaryTreeNode right){this.Data = data;this.leftChild = left;this.rightChild = right;}
}

2解题思路与实现

核心思路:

首先,通过下图了解遍历上图中的二叉树的过程:

通过上图可以总结出规律:

(1)当用前序遍历的方式访问到某一结点时,我们把该结点添加到路径上,并累加该结点的值。

(2)如果该结点为叶结点并且路径中结点值的和刚好等于输入的整数,则当前的路径符合要求,我们把它打印出来。如果当前结点不是叶结点,则继续访问它的子结点。

(3)当前结点访问结束后,递归函数将自动回到它的父结点。这里要注意的是:在函数退出之前要在路径上删除当前结点并减去当前结点的值,以确保返回父结点时路径刚好是从根结点到父结点的路径。

代码实现:

public static void FindPath(BinaryTreeNode root, int expectedSum)
{if (root == null){return;}int currentSum = 0;List<int> path = new List<int>();FindPath(root, expectedSum, path, ref currentSum);
}private static void FindPath(BinaryTreeNode root, int expectedSum, List<int> path, ref int currentSum)
{currentSum += root.Data;path.Add(root.Data);// 如果是叶结点,并且路径上结点的和等于输入的值// 打印出这条路径bool isLeaf = root.leftChild == null && root.rightChild == null;if (isLeaf && currentSum == expectedSum){foreach (int data in path){Console.Write("{0}\t", data);}Console.WriteLine();}// 如果不是叶结点,则遍历它的子结点if (root.leftChild != null){FindPath(root.leftChild, expectedSum, path, ref currentSum);}if (root.rightChild != null){FindPath(root.rightChild, expectedSum, path, ref currentSum);}// 在返回到父结点之前,在路径上删除当前结点,// 并在currentSum中减去当前结点的值path.Remove(root.Data);currentSum -= root.Data;
}

3单元测试

测试辅助方法:

private static void TestPortal(string testName, BinaryTreeNode root, int expectedSum)
{if (!string.IsNullOrEmpty(testName)){Console.WriteLine("{0} begins:", testName);}FindPath(root, expectedSum);Console.WriteLine();
}private static void SetSubTreeNode(BinaryTreeNode root, BinaryTreeNode lChild, BinaryTreeNode rChild)
{if (root == null){return;}root.leftChild = lChild;root.rightChild = rChild;
}private static void ClearUpTreeNode(BinaryTreeNode root)
{if (root != null){BinaryTreeNode left = root.leftChild;BinaryTreeNode right = root.rightChild;root = null;ClearUpTreeNode(left);ClearUpTreeNode(right);}
}

单元测试用例:

//            10
//         /      \
//        5        12
//       /\        
//      4  7     
// 有两条路径上的结点和为22
public static void Test1()
{BinaryTreeNode node10 = new BinaryTreeNode(10);BinaryTreeNode node5 = new BinaryTreeNode(5);BinaryTreeNode node12 = new BinaryTreeNode(12);BinaryTreeNode node4 = new BinaryTreeNode(4);BinaryTreeNode node7 = new BinaryTreeNode(7);SetSubTreeNode(node10, node5, node12);SetSubTreeNode(node5, node4, node7);Console.WriteLine("Two paths should be found in Test1.");TestPortal("Test1", node10, 22);ClearUpTreeNode(node10);
}//            10
//         /      \
//        5        12
//       /\        
//      4  7     
// 没有路径上的结点和为15
public static void Test2()
{BinaryTreeNode node10 = new BinaryTreeNode(10);BinaryTreeNode node5 = new BinaryTreeNode(5);BinaryTreeNode node12 = new BinaryTreeNode(12);BinaryTreeNode node4 = new BinaryTreeNode(4);BinaryTreeNode node7 = new BinaryTreeNode(7);SetSubTreeNode(node10, node5, node12);SetSubTreeNode(node5, node4, node7);Console.WriteLine("No paths should be found in Test2.");TestPortal("Test2", node10, 15);ClearUpTreeNode(node10);
}//               5
//              /
//             4
//            /
//           3
//          /
//         2
//        /
//       1
// 有一条路径上面的结点和为15
public static void Test3()
{BinaryTreeNode node5 = new BinaryTreeNode(5);BinaryTreeNode node4 = new BinaryTreeNode(4);BinaryTreeNode node3 = new BinaryTreeNode(3);BinaryTreeNode node2 = new BinaryTreeNode(2);BinaryTreeNode node1 = new BinaryTreeNode(1);node5.leftChild = node4;node4.leftChild = node3;node3.leftChild = node2;node2.leftChild = node1;Console.WriteLine("One path should be found in Test3.");TestPortal("Test3", node5, 15);ClearUpTreeNode(node5);
}// 1
//  \
//   2
//    \
//     3
//      \
//       4
//        \
//         5
// 没有路径上面的结点和为16
public static void Test4()
{BinaryTreeNode node1 = new BinaryTreeNode(1);BinaryTreeNode node2 = new BinaryTreeNode(2);BinaryTreeNode node3 = new BinaryTreeNode(3);BinaryTreeNode node4 = new BinaryTreeNode(4);BinaryTreeNode node5 = new BinaryTreeNode(5);node1.leftChild = node2;node2.leftChild = node3;node3.leftChild = node4;node4.leftChild = node5;Console.WriteLine("No paths should be found in Test4.");TestPortal("Test4", node1, 16);ClearUpTreeNode(node1);
}// 树中只有1个结点
public static void Test5()
{BinaryTreeNode node1 = new BinaryTreeNode(1);Console.WriteLine("One paths should be found in Test5.");TestPortal("Test5", node1, 1);ClearUpTreeNode(node1);
}// 树中没有结点
public static void Test6()
{Console.WriteLine("No paths should be found in Test6.");TestPortal("Test6", null, 0);
}

测试结果:

测试的结果情况如下图:

Ref参考资料

何海涛,《剑指Offer》

后台回复:剑指offer,即可获得pdf下载链接哟!

????扫码关注EdisonTalk

设为星标,不再失联!

往期推文合集:2020年上半年推文合集

成都新鲜坑位:喜鹊生活招聘.NET开发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307422.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode459. 重复的子字符串(KMP)

一:题目 二:上码 class Solution { public:/**思路:a b c a b c a b c a b cnext[i] 0 0 0 1 2 3 4 5 6 7 8 9i 0 1 2 3 4 5 6 7 8 9 10 11 length:12next[length-1]:next[11] 9length - next[length-1] 3;//求出我们的单个字符串如果length % (length - next[length-1]…

AA.Dapper升级了

AA.Dapper如何使用AA.Dapper基于dapper进一步封装而成的orm框架&#xff0c;提供增删改查、分页、事务、原生sql的功能&#xff0c;以满足日常的业务开发。1&#xff0e;Repository层&#xff1a;DapperRepository类包含大部分数据库操作如图&#xff1a; DapperContext.Curren…

剑指 Offer 05. 替换空格(java双指针)

一:题目 二:上码 class Solution {/**思路:1.双指针法进行解决2.我们先统计出空格的数量,然后再按空格数*2,扩充成字符串&#xff0c;加入到原来的字符串中3.然后我们定义两个指针 一个是原来数组长度的指针 一个是扩充完数组长度下标的指针4.当我们原来数组长度的指针遇见空…

如何使用 dotTrace 来诊断 netcore 应用的性能问题

最近在为 Newbe.Claptrap 做性能升级&#xff0c;因此将过程中使用到的 dotTrace 软件的基础用法介绍给各位开发者。Newbe.Claptrap 是一个用于轻松应对并发问题的分布式开发框架。如果您是首次阅读本系列文章。建议可以先从本文末尾的入门文章开始了解。开篇摘要dotTrace 是 J…

leetcode232. 用栈实现队列

一:题目 二:上码 class MyQueue { public:/**思路:1.设置两个栈,一个In,一个out,2.模拟入队的话 其实就是 往栈中添加元素3.模拟出队的话&#xff0c;那么是先进先出的 ,我们需要将in中的元素 导入到 out 中&#xff0c;然后出队的话其实也就是 out栈中的栈顶元素。*/stack<…

用.NetCore 编译国产老牌PHP论坛DiscuzX ,世界上最好的语言从此属于.Net 的一员

DiscuzX是北京康盛新创科技有限责任公司推出的一套通用的社区论坛软件系统。自2001年6月面世以来&#xff0c;Discuz!已拥有15年以上的应用历史和200多万网站用户案例&#xff0c;是全球成熟度最高、覆盖率最大的论坛软件系统之一。目前最新版本Discuz! X3.4正式版于2017年8月2…

leetcode225. 用队列实现栈

一:题目 二:上码 class MyStack { private:/**思路:1.我们每次push的时候 先push进队列,然后的话,将该元素前面的元素都出队重新push进该队列的尾部*/queue<int>q; public:/** Initialize your data structure here. */MyStack() {}/** Push element x onto stack. */voi…

使用 .NET 进行游戏开发

微软是一家综合性的网络公司&#xff0c;相信这点来说不用过多的赘述&#xff0c;没有人不知道微软这个公司&#xff0c;这些年因为游戏市场的回报&#xff0c;微软收购了很多的游戏公司还有独立工作室&#xff0c;MC我的世界就是最成功的的案例&#xff0c;现在市值是排在全世…

leetcode20. 有效的括号

一:题目 二:上码 class Solution { public:/**思路:- 这个题厉害之处在于其遍历到符号的左半部分的时候,我们是将对应的右半部分入队的- 那么如果存在对应的元素的话,那么我们就可以判断跟栈顶元素是否相等。*/bool isValid(string s) {stack<char> st;for (int i 0; i …

为什么我们总是「习惯性辩解」?

这里是Z哥的个人公众号每周五11&#xff1a;45 按时送达当然了&#xff0c;也会时不时加个餐&#xff5e;我的第「162」篇原创敬上大家好&#xff0c;我是Z哥。今天我们来讨论一个日常工作中很常见的现象&#xff1a;面对质疑&#xff0c;我们的第一反应是不承认&#xff0c;甚…

leetcode1047. 删除字符串中的所有相邻重复项

一:题目 二:上码 class Solution { public:string removeDuplicates(string s) {stack<char>st;string str;st.push(s[0]);for (int i 1; i < s.size(); i) {if (!st.empty() && s[i] st.top()) {//此时s[i]也没有入栈st.pop();} else {st.push(s[i]);}}whi…

如何理解Eating这个词?云原生与微服务专场介绍

点击上方“开源社”关注我们| 作者&#xff1a;开源社| 编辑&#xff1a;李明康| 责编&#xff1a;袁睿斌有一幅曾经传播很广的漫画&#xff0c;大意是&#xff1a;软件吞噬世界&#xff0c;开源吞噬软件。后来这个漫画又被人加了两条鱼&#xff1a;云计算吞噬开源&#xff0c;…

leetcode239. 滑动窗口最大值(java详解)

一:题目 二:思路 1:lc通过版 class Solution {/*思路:1.这里是要求出每一个窗口中的最大值,那么我们自然的想到如何用一个队列 可以使其每次队首出现最大值&#xff0c;那么我自然回想到大顶堆,但是用了之后&#xff0c;我们窗口中的元素位置就发生了变化那么当我们移动窗口的…

程序员修神之路--它可能是分布式系统中最重要的枢纽

“灵魂拷问分布式系统为什么需要注册中心呢&#xff1f;分布式系统注册中心有哪些坑&#xff1f;分布式系统注册中心怎么来实现呢&#xff1f;注册中心利用现成的组件很好实现吗&#xff1f;看到标题你可能会鄙视一下&#xff0c;注册中心有是什么讲的。注册中心作为现在架构中…

用Java刷算法题的常用数据结构(C++转Java)

文章目录一:前言1:为何刷题从C转java2:如何上手呢&#xff1f;二:输入1:常规的输入2:关于其他输入符在nextLine()之前用吃掉回车符的问题解决3:常见输入之我们输入一串数到容器中三:常用的数据结构1:数组2.List3:Map4:Set5.栈6:队列一:前言 1:为何刷题从C转java 平时除了写项…

Magicodes.IE 2.4发布

今天我们发布了2.4版本&#xff0c;这离不开大家对Magicodes.IE的支持&#xff0c;我们也对大家的意见以及需求不断的进行更新迭代&#xff0c;目前我们的发布频率平均在一周一个beta版本&#xff0c;一个月一个正式版本的更新&#xff0c;我们欢迎更多的开发者加入进来&#x…

7-1 简单词法分析

一:题目 二:思路 思路: 1.记得看书;不要一上来就莽;不然莽不过去的 2.这里我从书中了解到 f(0,b) 0; f(0,a) 1;f(1,c)1;f(1,b)3… 那么的话我们只要最终推导出f(1,b)3;那么的话就是一个满足要求的字符串; 注意我们入口部分一定是从 0 开始; 3.接下来就是要判断一些细枝末节 …

Java 生态碎片化 和 .NET生态的一致性

.NET Core是以MIT协议开源&#xff0c; Java是GPL协议开源。Java 8 SDK升级Oracle要收费这件事对于很多小公司是有着重大的影响的&#xff0c;Java生态越发碎片化&#xff0c;有众多的OpenJDK发行版&#xff0c;腾讯云和阿里都有OpenJDK发行版&#xff0c;龙芯也有MIPS版本的Op…

Power Automate Desktop概览

点击蓝字关注我们Microsoft Power Automate使得通过自动化重复性、耗时的任务来提高您的业务效率成为可能。Power Automate提供了一种更好的方法&#xff0c;通过数字和机器人过程自动化(RPA)在整个组织中完成任务。Microsoft Ignite 在线活动小伙伴们都有参加么&#xff1f;重…

超600人!近5小时直播!录屏+彩蛋+PPT…你要的都在这!

2020年9月26日下午&#xff0c;《NCF框架揭秘》直播交流会圆满落幕&#xff01;由盛派首席架构师苏震巍老师主持、分享&#xff0c;更有各路大咖&#xff0c;在线助力&#xff0c;干货满满&#xff01;点击视频 ☝ 回顾直播现场友情提示&#xff1a;如果公众号内视频无法显示高…