​力扣解法汇总1048. 最长字符串链

news/2024/7/5 3:22:59

 目录链接:

力扣编程题-解法汇总_分享+记录-CSDN博客

GitHub同步刷题项目:

https://github.com/September26/java-algorithms

原题链接:力扣


描述:

给出一个单词数组 words ,其中每个单词都由小写英文字母组成。

如果我们可以 不改变其他字符的顺序 ,在 wordA 的任何地方添加 恰好一个 字母使其变成 wordB ,那么我们认为 wordA 是 wordB 的 前身 。

  • 例如,"abc" 是 "abac" 的 前身 ,而 "cba" 不是 "bcad" 的 前身

词链是单词 [word_1, word_2, ..., word_k] 组成的序列,k >= 1,其中 word1 是 word2 的前身,word2 是 word3 的前身,依此类推。一个单词通常是 k == 1 的 单词链 。

从给定单词列表 words 中选择单词组成词链,返回 词链的 最长可能长度 。
 

示例 1:

输入:words = ["a","b","ba","bca","bda","bdca"]
输出:4
解释:最长单词链之一为 ["a","ba","bda","bdca"]

示例 2:

输入:words = ["xbc","pcxbcf","xb","cxbc","pcxbc"]
输出:5
解释:所有的单词都可以放入单词链 ["xb", "xbc", "cxbc", "pcxbc", "pcxbcf"].

示例 3:

输入:words = ["abcd","dbqca"]
输出:1
解释:字链["abcd"]是最长的字链之一。
["abcd","dbqca"]不是一个有效的单词链,因为字母的顺序被改变了。

提示:

  • 1 <= words.length <= 1000
  • 1 <= words[i].length <= 16
  • words[i] 仅由小写英文字母组成。

解题思路:

* 解题思路:
* 构建一个Map<Integer, Map<String, Integer>>类型的map,key代表字符串长度,value的Map代表每个字符串的单词链最长长度。
* 然后按照单词的长度分组。
* 分别遍历单词的长度length分别遍历,每次遍历时,去查找length-1长度的map中,是否有满足要求的,如果有,则在其长度上+1,如果没有,则长度设置为1。

代码:

public class Solution1048 {
    int mMax = 1;

    public int longestStrChain(String[] words) {
        Arrays.sort(words, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.length() - o2.length();
            }
        });
        TreeMap<Integer, List<String>> tree = new TreeMap<>();
        for (String str : words) {
            int length = str.length();
            List<String> strings = tree.get(length);
            if (strings == null) {
                strings = new ArrayList<>();
                tree.put(length, strings);
            }
            strings.add(str);
        }
        Map<Integer, Map<String, Integer>> map = new HashMap<>();
        for (int i = 0; i <= 16; i++) {
            map.put(i, new HashMap<>());
        }

        for (int length : tree.keySet()) {
            List<String> strings = tree.get(length);
            search(length, strings, map);
        }
        return mMax;
    }

    public void search(int length, List<String> list, Map<Integer, Map<String, Integer>> map) {
        Map<String, Integer> shortMap = map.get(length - 1);
        Map<String, Integer> longMap = map.get(length);
        for (String str : list) {
            for (String key : shortMap.keySet()) {
                if (isMatch(key, str)) {
                    int newLength = shortMap.get(key) + 1;
                    longMap.put(str, Math.max(newLength, longMap.getOrDefault(str, 0)));
                    mMax = Math.max(mMax, newLength);
                }
            }
            if (longMap.get(str) == null) {
                longMap.put(str, 1);
            }
        }
    }

    public boolean isMatch(String shortStr, String longStr) {
        if ((longStr.length() - shortStr.length()) != 1) {
            return false;
        }
        char[] chars1 = shortStr.toCharArray();
        char[] chars2 = longStr.toCharArray();
        int num = 0;
        for (int i = 0; i < chars2.length; i++) {
            if (i - num == chars1.length) {
                return true;
            }
            if (chars1[i - num] == chars2[i]) {
                continue;
            }
            num++;
            if (num > 1) {
                return false;
            }
        }
        return true;
    }
}


http://lihuaxi.xjx100.cn/news/1075827.html

相关文章

docker-Dockerfile文件使用配置、自定义构建镜像、docker build

Dockerfile使用 docker build构建新的镜像参数解释 Dockerfile格式基础格式FROMCOPYADDRUNCMDENTRYPOINTENVARGVOLUMEEXPOSEWORKDIRUSERHEALTHCHECKONBUILDLABEL 命令摘要 docker build构建新的镜像 命令&#xff1a;docker build -t some-content-nginx . 参数解释 docker …

微服务学习笔记--(认识微服务)

目录 认识微服务分布式服务架构案例euraka注册中心Ribbon负载均衡原理nacos注册中心 认识微服务-服务架构演变 单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署。 优点&#xff1a; 架构简单部署成本低 缺点&#xff1a; …

网络模型与 IO 多路复用

一、基础概念1. socket2. FD&#xff1a;file descriptor**3. 内核态和用户态 二、 IO 多路复用1. 常见的IO模型2. 同步和异步3. 阻塞和非阻塞 三、 阻塞IO四、非阻塞 IO1、针对 read 函数造成的阻塞2、针对 accept函数造成的阻塞3、 select 模型4、poll模型5、epoll模型 一、基…

RUST 每日一省:生命周期作用域

生命周期 一个变量的生命周期就是它从创建到销毁的整个过程。 作用域 我们声明的每个变量都有作用域。作用域其实是变量和值存在的环境。作用域是由一对花括号表示的。例如&#xff0c;使用块表达式会创建一个作用域&#xff0c;即任何以花括号开头和结尾的表达式。此…

关于业务缓存的存储结构

问&#xff1a;为什么不直接缓存 [账号id->权限列表]的关系&#xff0c;而是 [账号id -> 角色id -> 权限列表]&#xff1f; 答&#xff1a;[账号id->权限列表]的缓存方式虽然更加直接粗暴&#xff0c;却有一个严重的问题&#xff1a; 通常我们系统的权限架构是RBA…

Reid之网络的定义代码详解

这篇文章是yolov5_reid的扩展。针对reid网络定义代码的详解&#xff0c;有助于大家的理解&#xff0c;同时也方便网络方面的改进。 数据集的预处理代码可以参考我另一篇文章&#xff1a;Reid数据集处理 本篇文章Reid的网络将以Resnet50为例。因此需要大家对Resnet代码有一定的…

Clickhouse分布式表引擎(Distributed)写入核心原理解析

Clickhouse分布式表引擎&#xff08;Distributed&#xff09;写入核心原理解析 Clickhouse分布式表引擎&#xff08;Distributed&#xff09;写入核心原理解析Clickhouse分布式表引擎&#xff08;Distributed&#xff09;查询核心原理解析 Distributed表引擎是分布式表的代名…

【接口自动化测试】月薪12k必会技术,从0到1学习接口自动化测试,6个操作安排的明明白白

导读&#xff1a;在所有的开发测试中&#xff0c;接口测试是必不可少的一项。有效且覆盖完整的接口测试&#xff0c;不仅能保障新功能的开发质量&#xff0c;还能让开发在修改功能逻辑的时候有回归的能力&#xff0c;同时也是能优雅地进行重构的前提。编写接口测试要遵守哪些原…