算法成长记:单词替换,合并二叉树

单词替换

在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。

现在,给定一个由许多词根组成的词典和一个句子。你需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。

你需要输出替换之后的句子。

输入:dictionary = [“cat”,“bat”,“rat”], sentence = “the cattle was rattled by the battery”
输出:“the cat was rat by the bat”

输入:dictionary = [“a”,“b”,“c”], sentence = “aadsfasf absbs bbab cadsfafs”
输出:“a a b c”

输入:dictionary = [“a”, “aa”, “aaa”, “aaaa”], sentence = “a aa a aaaa aaa aaa aaa aaaaaa bbb baba ababa”
输出:“a a a a a a a a bbb baba a”

思考:先看懂规律,是继承词替换词根,遍历每个单词,循环是否有词根,重新赋值
注意:词根出现的位置必须是在首部,而不是中间或者其他位置。

/**
 * @param {string[]} dictionary
 * @param {string} sentence
 * @return {string}
 */
var replaceWords = function(dictionary, sentence) {
    // 用词根组成的词来替换成词根本身
    // 注意的问题:顺序,词根是在前面的
    // 问题怎么遍历字符串的每个单词:转换成数组split
    // 对每个单词做匹配,注意是开头可以匹配哦,这里使用startWith来匹配 如果是,就替换
    let sen = sentence.split(' ')
    let n = sen.length
    // 循环
    for (let i=0;i<n;i++) {
        for (let j =0;j<dictionary.length;j++) {
            if (sen[i].startsWith(dictionary[j])) {
            sen[i] = dictionary[j]
        }
        }  
    }
    return sen.join(' ')
};

合并二叉树

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1:

输入: 
	Tree 1                     Tree 2                  
          1                         2                             
         / \                       / \                            
        3   2                     1   3                        
       /                           \   \                      
      5                             4   7                  
输出: 
合并后的树:
	     3
	    / \
	   4   5
	  / \   \ 
	 5   4   7

思考:题目比较好理解,那么我们应该采用什么方法呢?一般二叉树我们会想到的是递归,因为他们的操作相似,比如说根节点的处理,左子树的处理,右子树的处理。那么我们需要注意的是每层需要处理的逻辑和递归的条件了

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root1
 * @param {TreeNode} root2
 * @return {TreeNode}
 */
var mergeTrees = function(root1, root2) {
    // 当至少有一个为空的时候
    if (!root1 || !root2) {
        return root1 || root2
    }
    // 递归的思想,先算出root1.val,root1.left,root2.left
    // oot1.val,root1.left,root2.left的结果最终可以使用递归的方式,像root1.val一样去计算
    root1.val = root1.val + root2.val
    root1.left = mergeTrees(root1.left,root2.left)
    root1.right = mergeTrees(root1.right,root2.right)
    return root1
};

比较注重的一种递归的思想。

每天坚持一点点吧,不要放弃。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
非常感谢您的问题。下面是我对您的问题的回答: 1. 构造二叉树的先序遍历算法: 首先我们需要了解先序遍历的规则。先序遍历的规则是,先访问当前节点,然后遍历其左子节点,最后遍历其右子节点。根据这个规则,我们可以从给定的先序序列中依次读取元素,先读取根节点,然后根据其下一位的值判断左子节点或右子节点是否存在。如果存在,就递归调用构造算法,否则返回None。具体实现可以参考下面的代码: ``` class Node: def __init__(self, value): self.val = value self.left = None self.right = None def build_tree(pre_order): if not pre_order: return None root_val = pre_order.pop(0) if root_val == 'Φ': return None root = Node(root_val) root.left = build_tree(pre_order) root.right = build_tree(pre_order) return root ``` 2. 统计二叉树中叶结点个数的递归算法: 二叉树中的叶节点是指没有左右子树的节点。我们可以通过递归对每个节点进行判断,如果该节点没有左右子树,则它就是叶节点。具体实现可以参考下面的代码: ``` def count_leaf_nodes(root): if not root: return 0 if not root.left and not root.right: return 1 return count_leaf_nodes(root.left) + count_leaf_nodes(root.right) ``` 3. 统计二叉树高度的递归算法: 二叉树高度的定义是从根节点到叶节点的最长路径长度。我们可以通过递归计算每个节点的高度,并递归返回左右子树的最大高度加1。具体实现可以参考下面的代码: ``` def get_height(root): if not root: return 0 left_height = get_height(root.left) right_height = get_height(root.right) return max(left_height, right_height) + 1 ``` 4. 在主函数中调用以上相关算法,先生成先序序列{ABDΦΦΦCEΦGΦΦFΦΦ}: 我们可以先将先序序列转换成列表,然后调用构造二叉树算法生成二叉树。接着调用统计叶节点个数和二叉树高度的算法进行计算。具体实现可以参考下面的代码: ``` pre_order = list('ABDΦΦΦCEΦGΦΦFΦΦ') root = build_tree(pre_order) leaf_count = count_leaf_nodes(root) height = get_height(root) print(f'叶节点个数:{leaf_count}') print(f'二叉树高度:{height}') ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值