leetcode 最长单词
题目链接
思路一:字典树+回溯
首先将数组进行排序,按照长度降序,一样的长度,再按照字典序升序。
再将所有的单词建立成一颗字典树,这是为了后面的查找效率。
再从前往后遍历查找每个单词,是否由其他单词拼凑出来。
找到的对一个就是答案。
代码:
class Solution {//字典树结构class DictionaryTree{char c;//是不是结尾boolean end;DictionaryTree[] children = new DictionaryTree[26];}public String longestWord(String[] words) {DictionaryTree root = new DictionaryTree();for(String word:words){//建树createDictionaryTree(root,word);}//排序好Arrays.sort(words,(s1,s2)->{return s1.length()!=s2.length() ? s2.length()- s1.length() : s1.compareTo(s2);});//遍历去字典树中查找for(String word:words){if(dfs(root,word,0)){return word;}}return "";}/**** @param root 字典树的根节点* @param word 需要查找的单词* @param start 查找的第一个下标* @return*/public boolean dfs(DictionaryTree root, String word, int start){//如果查找的第一个下标等于最后了,就说明前面的全部查找到了if(start == word.length()){return true;}//遍历这个单词中的每个字母for(int end = start;end<word.length();end++){//这行代码比较关键,因为字典树中一定能查找出来最开始的单词,因为被查找的单词自身就在字典树中,所以要排除自身if(end-start+1 == word.length()){continue;}//将[start,end]切下来String pre = word.substring(start, end+1);//查找root中是否存在pre 如果存在了,说明可以进下一层,从end+1个开始找,因为[start,end]已经找到了if(findWord(root,pre) && dfs(root,word,end+1)){return true;}}return false;}/**** @param root 根节点,会持续更新的* @param word 需要查找的单词* @return 查找结果*/public boolean findWord(DictionaryTree root, String word){//根节点如果都不存在word单词第一个开头的字母,那肯定没有这个wordif(root.children[word.charAt(0)-'a']==null){return false;}else if(word.length()==1){//到了最后一个单词了,直接返回是不是结尾,如果是,就是一个word,否则就不是 例如 [apple]中寻找app,是找不到的,因为虽然能匹配到app,但是p并不是结尾return root.children[word.charAt(0)-'a'].end;}//进入下一层,此时下一层根节点应该是当前节点对应的孩子节点,word也切除第一个字母return findWord(root.children[word.charAt(0)-'a'],word.substring(1));}/**** @param root 根节点* @param word 需要被建立的单词*/public void createDictionaryTree(DictionaryTree root,String word){//没了,那么此时根节点就是最后一个字母了,就是结尾了if(word.length()==0){root.end = true;return;}DictionaryTree[] children = root.children;//判断是否建立以word第一个字母开头的孩子节点if(children[word.charAt(0) - 'a']==null){DictionaryTree dictionaryTree = new DictionaryTree();dictionaryTree.c = word.charAt(0);children[word.charAt(0) - 'a'] = dictionaryTree;}//进入下一层,下一层的根节点应该是这一层相应的孩子节点,word也要切除第一个,因为第一个应该被建立出来了createDictionaryTree(children[word.charAt(0) - 'a'],word.substring(1));}
}
缺点:有很多重复的查找,例如查找worker,会查找 w wo work worke worker
w查了五次。。
思路二:暴力深搜
代码:
public String longestWordII(String[] words) {String ans = "";for(int i = 0;i<words.length;i++){if(ans.length()>words[i].length() || (ans.length() == words[i].length() && words[i].compareTo(ans) > 0)){continue;}if(dfs(words,words[i],i)){ans = words[i];}}return ans;}/*** * @param words 单词表* @param word 要查找的单词* @param index 单词在单词表中的下标* @return*/public boolean dfs(String[] words,String word, int index){for(int i = 0; i < words.length;i++){//排除自身 和 比自身长的单词 因为比自己长的单词,肯定无法拼凑出自己if(i == index || words[i].length() > word.length()){continue;}//如果word[i]正好就等于自己,说明word可以被拼出来 word是由word[i]开头的,那么进下一层循环,word切除word[i],将后面的单词再进行拼,下标改成-1,是因为下一层的单词已经不是原始单词了if(word.equals(words[i]) || word.startsWith(words[i]) && dfs(words,word.substring( words[i].length() ),-1)){return true;}}return false;}
leetcode 最长单词相关推荐
- leetcode - 最长单词
题目 给定一组单词words,编写一个程序,找出其中的最长单词,且该单词由这组单词中的其他单词组合而成.若有多个长度相同的结果,返回其中字典序最小的一项,若没有符合要求的单词则返回空字符串. 示例: ...
- LeetCode刷题实战524:通过删除字母匹配到字典里最长单词
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...
- leetcode面试题 17.15. 最长单词
给定一组单词words,编写一个程序,找出其中的最长单词,且该单词由这组单词中的其他单词组合而成.若有多个长度相同的结果,返回其中字典序最小的一项,若没有符合要求的单词则返回空字符串. 示例: 输入: ...
- Leetcode刷题100天—524. 通过删除字母匹配到字典里最长单词(双指针)—day38
前言: 作者:神的孩子在歌唱 大家好,我叫运智 524. 通过删除字母匹配到字典里最长单词 难度中等192收藏分享切换为英文接收动态反馈 给你一个字符串 s 和一个字符串数组 dictionary 作 ...
- leetcode记录-524-通过删除字母匹配到字典里最长单词-双指针
524.通过删除字母匹配到字典里最长单词 思路 理解题意是一大难点...对于list中的字符串,如果可以由s删除一些字符得到,那么这个字符串初步符合标准,把他和str(初始为空)的比较,如果其长度更长 ...
- LeetCode 244. 最短单词距离 II(哈希map+set二分查找)
文章目录 1. 题目 2. 解题 2.1 暴力超时 2.2 哈希表+set二分查找 1. 题目 请设计一个类,使该类的构造函数能够接收一个单词列表. 然后再实现一个方法,该方法能够分别接收两个单词 w ...
- LeetCode 245. 最短单词距离 III
文章目录 1. 题目 2. 解题 1. 题目 给定一个单词列表和两个单词 word1 和 word2,返回列表中这两个单词之间的最短距离. word1 和 word2 是有可能相同的,并且它们将分别表 ...
- LeetCode 243. 最短单词距离
文章目录 1. 题目 2. 解题 1. 题目 给定一个单词列表和两个单词 word1 和 word2,返回列表中这两个单词之间的最短距离. 示例: 假设 words = ["practice ...
- 程序员面试金典 - 面试题 17.15. 最长单词(排序+递归)
1. 题目 给定一组单词words,编写一个程序,找出其中的最长单词,且该单词由这组单词中的其他单词组合而成. 若有多个长度相同的结果,返回其中字典序最小的一项,若没有符合要求的单词则返回空字符串. ...
最新文章
- 编辑从字节码和 JVM 的角度解析 Java 核心类 String 的不可变特性
- C/Cpp / STL / map 的 key 为自定义的 struct 或者 class 时,有什么注意事项?
- python不支持_为什么 Python 不支持函数重载?而其他语言大都支持?
- 8 WM配置-主数据-定义门(Dock Door)
- (补充)【打印1到最大的n位数】剑指offer——面试题12:打印1到最大的n位数
- windows 2008 64位oracle11g部署问题(1)之警告-启动database control时出错
- (3)机器学习_逻辑模型_决策树
- php 处理vue上传图片 base64_encode file_put_contents file_get_contents
- 阿里云何登成:开放平台助力企业高效上云管云 | 云栖大会
- flutter 加载gif图片
- 推荐几款程序员值得拥有的写文档工具
- B46 - STM32太阳能充电智能心率监测骑行仪
- 给图片加水印最简单的方法
- 双摄测距原理_双摄像头系列原理深度剖析
- 泰拉瑞亚 服务器linux,泰拉瑞亚Linux主机打造指南
- python ADF单位根检验,序列平稳性检验
- PR-颜色遮罩-透明度-渐闪效果
- win10最简单定时关机命令
- WPS JS宏示例——工作表排序
- vue中import引入模块路径中@符号是什么意思