作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/smallest-string-starting-from-leaf/

题目描述

Given the root of a binary tree, each node has a value from 0 to 25 representing the letters ‘a’ to ‘z’: a value of 0 represents ‘a’, a value of 1 represents ‘b’, and so on.

Find the lexicographically smallest string that starts at a leaf of this tree and ends at the root.

(As a reminder, any shorter prefix of a string is lexicographically smaller: for example, "ab" is lexicographically smaller than "aba". A leaf of a node is a node that has no children.)

Example 1:

Input: [0,1,2,3,4,3,4]
Output: "dba"

Example 2:

Input: [25,1,3,1,3,0,2]
Output: "adz"

Example 3:

Input: [2,2,1,null,1,0,null,0]
Output: "abc"

Note:

  1. The number of nodes in the given tree will be between 1 and 1000.
  2. Each node in the tree will have a value between 0 and 25.

题目大意

一个二叉树每个节点上面是个025的数字代表了az各个数字,从叶子节点走向根节点的路径可以看做一个字符串,现在求所有字符串中字典顺序最小的那个是什么。

解题方法

DFS

既然题目说了,要求所有字符串字典顺序中最小的那个,我们简单的方法就是把所有的字符串都求出来然后排序啊!

可以使用DFS把所有的根节点到叶子节点的路径保存下来,由于DFS遍历一定是由上向下的,但是题目要求的是叶子节点到根节点才是路径,所以拼接的时候把每个节点的字符放到路径的前面即可。

这就是普通的DFS,需要提醒注意的是:1.dfs()函数的声明中,path必须是个值传递,res必须是个引用传递。原因是每条路径的path不同,所以需要值传递进行拷贝,但是res是我们定义的同一个res,所以必须使用引用传递。2.在C++中,char可以直接和string相加,无论谁在前谁在后,这个是C++的运算符重载和友元函数定义共同构成的特性。3.没有使用常见的当遍历到空节点的时候才把结果放进去,假如这样做,每个叶子节点会放进去两个相同的字符串,倒也不影响最终的结果。4.题目中已经说了,给出的树最少有一个节点,所以直接dfs的时候不会有空指针。

C++代码如下:

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
string smallestFromLeaf(TreeNode* root) {
vector<string> res;
dfs(root, "", res);
sort(res.begin(), res.end());
return res[0];
}
void dfs(TreeNode* root, string path, vector<string>& res) {
if (!root->left && !root->right) {
res.push_back(char('a' + root->val) + path);
return;
}
if (root->left)
dfs(root->left, char('a' + root->val) + path, res);
if (root->right)
dfs(root->right, char('a' + root->val) + path, res);
}
};

python代码如下:

# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None class Solution(object):
def smallestFromLeaf(self, root):
"""
:type root: TreeNode
:rtype: str
"""
res = []
self.dfs(root, "", res)
res.sort()
return res[0] def dfs(self, root, path, res):
if not root.left and not root.right:
res.append(chr(root.val + ord('a')) + path)
return
if root.left:
self.dfs(root.left, chr(root.val + ord('a')) + path, res)
if root.right:
self.dfs(root.right, chr(root.val + ord('a')) + path, res)

BFS

这个题同样也可以使用BFS来解决,遍历的方法也是从上向下进行遍历,我们使用的方式是使用队列同时保存节点和当前节点未加入字符串时的字符串。然后同样当这个节点是叶子节点的时候,把路径保存到列表中。后面排序取字典序最小的即可。

我发现我容易犯一个手误,那就是在BFS的while循环中,把node不知不觉得就写成了root造成了死循环……注意啊!

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
string smallestFromLeaf(TreeNode* root) {
queue<pair<TreeNode*, string>> q;
q.push({root, ""});
vector<string> res;
while (!q.empty()) {
auto h = q.front(); q.pop();
TreeNode* node = h.first;
string path = h.second;
if (!node->left && !node->right) {
res.push_back(char(node->val + 'a') + path);
continue;
}
if (node->left)
q.push({node->left, char(node->val + 'a') + path});
if (node->right)
q.push({node->right, char(node->val + 'a') + path});
}
sort(res.begin(), res.end());
return res[0];
}
};

python版本的BFS如下。

# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None class Solution(object):
def smallestFromLeaf(self, root):
"""
:type root: TreeNode
:rtype: str
"""
q = collections.deque()
q.append((root, ""))
res = []
while q:
node, path = q.popleft()
if not node.left and not node.right:
res.append(chr(node.val + ord('a')) + path)
continue
if node.left:
q.append((node.left, chr(node.val + ord('a')) + path))
if node.right:
q.append((node.right, chr(node.val + ord('a')) + path))
res.sort()
return res[0]

日期

2019 年 2 月 20 日 —— 少刷知乎多做题

【LeetCode】988. Smallest String Starting From Leaf 解题报告(C++ & Python)的更多相关文章

  1. LeetCode 988. Smallest String Starting From Leaf

    原题链接在这里:https://leetcode.com/problems/smallest-string-starting-from-leaf/ 题目: Given the root of a bi ...

  2. LC 988. Smallest String Starting From Leaf

    Given the root of a binary tree, each node has a value from 0 to 25 representing the letters 'a' to  ...

  3. 【leetcode】988. Smallest String Starting From Leaf

    题目如下: Given the root of a binary tree, each node has a value from 0 to 25representing the letters 'a ...

  4. 【LeetCode】792. Number of Matching Subsequences 解题报告(Python)

    [LeetCode]792. Number of Matching Subsequences 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://f ...

  5. 【LeetCode】802. Find Eventual Safe States 解题报告(Python)

    [LeetCode]802. Find Eventual Safe States 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemi ...

  6. 【LeetCode】166. Fraction to Recurring Decimal 解题报告(Python)

    [LeetCode]166. Fraction to Recurring Decimal 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingz ...

  7. 【LeetCode】556. Next Greater Element III 解题报告(Python)

    [LeetCode]556. Next Greater Element III 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人 ...

  8. 【LeetCode】522. Longest Uncommon Subsequence II 解题报告(Python)

    [LeetCode]522. Longest Uncommon Subsequence II 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemin ...

  9. 【LeetCode】449. Serialize and Deserialize BST 解题报告(Python)

    [LeetCode]449. Serialize and Deserialize BST 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/pro ...

随机推荐

  1. MySQL深层理解,执行流程

    MySQL是一个关系型数据库,关联的数据保存在不同的表中,增加了数据操作的灵活性. 执行流程 MySQL是一个单进程服务,每一个请求用线程来响应, 流程: 1,客户请求,服务器开辟一个线程响应用户. ...

  2. Identity Server 4 从入门到落地(四)—— 创建Web Api

    前面的部分: Identity Server 4 从入门到落地(一)-- 从IdentityServer4.Admin开始 Identity Server 4 从入门到落地(二)-- 理解授权码模式 ...

  3. nit是虱子的卵

    如题.[牛津] (egg of a) louse or other parasitic insect 虱或其他寄生虫(的卵). 忘了在那个帖子里说nit: 虱子了. 为了凑字数,迄今为止六级/考研单词 ...

  4. 零基础学习java------20---------反射

    1. 反射和动态代理 参考博文:https://blog.csdn.net/sinat_38259539/article/details/71799078 1.0 什么是Class: 我们都知道,对象 ...

  5. C++构造函数和析构函数初步认识

    构造函数 1.构造函数与类名相同,是特殊的公有成员函数.2.构造函数无函数返回类型说明,实际上构造函数是有返回值的,其返回值类型即为构造函数所构建到的对象.3.当新对象被建立时,构造函数便被自动调用, ...

  6. Linux系统中安装软件方法总结

    Linux系统中安装软件方法总结 [1]Linux系统中安装软件的几种方式 [2] Linux配置yum源(本地源和网络源) [3] SuSE下zypper源配置 [4] SUSE zypper 本地 ...

  7. 为什么CTR预估使用AUC来评估模型?

    ctr预估简单的解释就是预测用户的点击item的概率.为什么一个回归的问题需要使用分类的方法来评估,这真是一个好问题,尝试从下面几个关键问题去回答. 1.ctr预估是特殊的回归问题 ctr预估的目标函 ...

  8. Android Loader异步装载

    一.Loader简介: (一).Loader的概念: 装载器从android3.0开始引进.它使得在activity或fragment中异步加载数据变得简单. 当成批显示数据的时候,为了使用户体验更好 ...

  9. IOS_UIButton去掉系统的按下高亮置灰效果

    setAdjustsImageWhenHighlighted   // default is YES. if YES, image is drawn darker when highlighted(p ...

  10. vue-cli4脚手架搭建一

    涉及内容 html  css   javascript   node.js   npm    webpack 2.9.6是常用版本 vue-cli4是基于webpack的 webpack是基于node ...