面试算法65:最短的单词编码

题目

输入一个包含n个单词的数组,可以把它们编码成一个字符串和n个下标。例如,单词数组[“time”,“me”,“bell”]可以编码成一个字符串"time#bell#“,然后这些单词就可以通过下标[0,2,5]得到。对于每个下标,都可以从编码得到的字符串中相应的位置开始扫描,直到遇到’#‘字符前所经过的子字符串为单词数组中的一个单词。例如,从"time#bell#"下标为2的位置开始扫描,直到遇到’#'前经过子字符串"me"是给定单词数组的第2个单词。给定一个单词数组,请问按照上述规则把这些单词编码之后得到的最短字符串的长度是多少?如果输入的是字符串数组[“time”,“me”,“bell”],那么编码之后最短的字符串是"time#bell#”,长度是10。

分析

这个题目的目标是得到最短的编码,因此,如果一个单词A是另一个单词B的后缀,那么单词A在编码字符串中就不需要单独出现,这是因为单词A可以通过在单词B中偏移下标得到。
前缀树是一种常见的数据结构,它能够很方便地表达一个字符串是另一个字符树串的前缀。这个题目是关于字符串的后缀。要把字符串的后缀转换成前缀也比较直观:如果一个字符串A是另一个字符串B的后缀,分别反转字符串A和B得到A’和B’,那么A’是B’的前缀。例如,把字符串"me"和"time"反转分别得到"em"和"emit","em"是"emit"的前缀。

public class Test {
   
    public static void main(String[] args) {
   
        String[] words = {
   "time", "me", "bell"};
        System.out.println(minimumLengthEncoding(words));
    }

    static class TrieNode {
   
        public TrieNode[] children;

        public TrieNode() {
   
            children = new TrieNode[26];
        }
    }

    public static int minimumLengthEncoding(String[] words) {
   
        TrieNode root = buildTrie(words);
        int[] total = {
   0};
        // 初始值为1,是因为每个单词后边有一个#号
        dfs(root, 1, total);
        return total[0];
    }

    private static TrieNode buildTrie(String[] words) {
   
        TrieNode root = new TrieNode();
        for (String word : words) {
   
            TrieNode node = root;
            for (int i = word.length() - 1; i >= 0; i--) {
   
                char ch = word.charAt(i);
                if (node.children[ch - 'a'] == null) {
   
                    node.children[ch - 'a'] = new TrieNode();
                }

                node = node.children[ch - 'a'];
            }
        }

        return root;
    }

    private static void dfs(TrieNode root, int length, int[] total) {
   
        boolean isLeaf = true;
        for (TrieNode child : root.children) {
   
            if (child != null) {
   
                isLeaf = false;
                dfs(child, length + 1, total);
            }
        }

        if (isLeaf) {
   
            total[0] += length;
        }
    }
}

相关推荐

  1. 面试算法65单词编码

    2023-12-23 01:04:02       60 阅读
  2. 面试算法63:替换单词

    2023-12-23 01:04:02       64 阅读
  3. 面试算法67异或

    2023-12-23 01:04:02       53 阅读
  4. 面试算法6/400-和至少为 K 子数组

    2023-12-23 01:04:02       32 阅读
  5. IOS面试编程机制 61-65

    2023-12-23 01:04:02       36 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-23 01:04:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-23 01:04:02       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-23 01:04:02       82 阅读
  4. Python语言-面向对象

    2023-12-23 01:04:02       91 阅读

热门阅读

  1. Macbook安装nvm以切换node版本

    2023-12-23 01:04:02       67 阅读
  2. nginx upstream 6种负载均衡策略介绍

    2023-12-23 01:04:02       52 阅读
  3. Android开发中实时语音开发之华为实时语音识别

    2023-12-23 01:04:02       64 阅读
  4. npm的使用技巧

    2023-12-23 01:04:02       52 阅读
  5. 基于MATLAB的模板匹配实现英文字母识别

    2023-12-23 01:04:02       56 阅读
  6. 做开发死路一条?一名五年全栈的看法

    2023-12-23 01:04:02       62 阅读
  7. junit-mock-controller

    2023-12-23 01:04:02       60 阅读
  8. Linux环境下通过journal命令查看和管理日志

    2023-12-23 01:04:02       60 阅读
  9. 基于粒子群算法的抽水蓄能电站优化调度研究

    2023-12-23 01:04:02       57 阅读