LeetCode算法题-Longest Word in Dictionary(Java实现)
这是悦乐书的第303次更新,第322篇原创
01 看题和准备
今天介绍的是LeetCode算法题中Easy级别的第171题(顺位题号是720)。给出表示英语词典的字符串单词数组,找到单词中长度最长的单词,此单词可以通过数组中的其他单词一次次构建一个字符而得来。如果有多个可能的答案,则返回字典顺序最小的最长单词。如果没有答案,则返回空字符串。例如:
输入:words = [“w”,“wo”,“wor”,“worl”,“world”]
输出:“world”
说明:“world”这个词可以通过“w”,“wo”,“wor”和“worl”一次构建一个字符。
输入:words = [“a”,“banana”,“app”,“appl”,“ap”,“apply”,“apple”]
输出:“apple”
说明:“apply”和“apple”都可以从字典中的其他单词构建。但是,“apple”在词典上比“apply”更小(靠前)。
注意:
输入中的所有字符串仅包含小写字母。
单词的长度将在[1,1000]范围内。
单词[i]的长度将在[1,30]的范围内。
本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。
02 第一种解法
在解题前,需要先注意题目中的几个信息,一是满足题目条件的结果字符串,是有一个个字符累加起来的,在我的一次提交中,有{"ew","ewq","ewqz"}这三个字符串,我的算法算出来是第三个"ewqz",但其实它还缺少一个"e",是不符合题目要求的。二是如果满足题目条件的字符串有两个或者多个,需要去比较谁更小,也就是按照字母顺序由小到大排列的,谁更靠前谁更小。
思路是先将字符串放进HashMap中,key为每一个单词,value为单词的长度。循环单词数组,比较谁的长度更小,此处分为两种情况处理:一是大于已有最大长度,二是等于已有最大长度,另外,无论遇到那种情况,都需要去判断当前字符是否是由单个单词一次次累加变成的,对此单独写了一个方法判断当前单词是否符合题目要求的方法isExists。针对第二种情况,需要去比较两个单词的大小,也写了一个额外的方法isMin来判断,如果满足,就将结果字符串更新,最长长度保持不变。
Map<String, Integer> map = new HashMap<String, Integer>();
public String longestWord(String[] words) {
for (String str : words) {
map.put(str, str.length());
}
int len = Integer.MIN_VALUE;
String result = "";
for (String str : words) {
if (isExists(str) && str.length() > len) {
result = str;
len = str.length();
} else if (isExists(str) && str.length() == len) {
if (result != "") {
if (isMin(str, result)) {
result = str;
}
}
}
}
return result;
}
/**
* 判断str是否小于str2
* @param str 新遇到的等长字符串
* @param str2 上一次的最长字符串
* @return true:str中的字符小于str2
*/
public boolean isMin(String str, String str2){
for (int i=0; i<str.length(); i++) {
if (str.charAt(i) < str2.charAt(i)) {
return true;
} else if (str.charAt(i) == str2.charAt(i)) {
continue;
} else {
return false;
}
}
return false;
}
/**
* 判断当前字符串在数组中是否是一个个字符慢慢累加起来的
* @param str
* @return
*/
public boolean isExists(String str) {
String ss = "";
for (char ch : str.toCharArray()) {
ss += ch;
if (!map.containsKey(ss)) {
return false;
}
}
return true;
}
03 第二种解法
在第一种解法中,并没有用到HashMap中的value值,因此可以使用HashSet来存储数组中的单词。其次,也可以通过数组排序的方式,省去后续循环中判断最长长度相等的情况,也省去了比较两个字符串谁更小的判断,更加的简洁。
Set<String> set = new HashSet<String>();
public String longestWord2(String[] words) {
Arrays.sort(words);
for (String word : words) {
set.add(word);
}
int len = Integer.MIN_VALUE;
String result = "";
for (String str : words) {
if (isExists2(str) && str.length() > len) {
result = str;
len = str.length();
}
}
return result;
}
public boolean isExists2(String str) {
String ss = "";
for (char ch : str.toCharArray()) {
ss += ch;
if (!set.contains(ss)) {
return false;
}
}
return true;
}
04 第三种解法
也可以只使用一个循环来解决。依旧是数组排序,使用HashSet存储数组中的单词,但是存入HashSet的操作是在循环中进行的,如果当前单词的长度等于1或者其本身的子串也存在于HashSet中,才存入HashSet,此步骤就相当于第一种解法和第二种解法中判断当前单词是否符合题目要求,由一个字符一次次累加得来的。如果当前字符的长度大于结果单词的长度,就进行赋值更新操作。
public String longestWord3(String[] words) {
Set<String> set = new HashSet<String>();
Arrays.sort(words);
String result = "";
for (String word : words) {
if (word.length() == 1 || set.contains(word.substring(0, word.length()-1))) {
if (word.length() > result.length()) {
result = word;
}
set.add(word);
}
}
return result;
}
05 第四种解法
我们也可以不借助排序来实现,其实也是对第二种解法的优化。依旧是使用HashSet,也借助了一个辅助方法isExists2来判断当前单词是否符合题目要求,但不同的是,在循环中,此判断只在当前单词长度大于结果单词的长度,或者两者长度相等且新单词小于结果单词这两种情况下进行,而不像第二种解法那样,每次都去先判断当前单词是否符合题目要求,再去比较长度。其中,比较两个单词的大小借助了字符串自带的compareTo方法。
Set<String> set = new HashSet<String>();
public String longestWord4(String[] words) {
for (String word : words) {
set.add(word);
}
String result = "";
for (String word : words) {
if (word.length() > result.length() || (word.length() == result.length() && word.compareTo(result) < 0)) {
if (isExists2(word)) {
result = word;
}
}
}
return result;
}
public boolean isExists2(String str) {
String ss = "";
for (char ch : str.toCharArray()) {
ss += ch;
if (!set.contains(ss)) {
return false;
}
}
return true;
}
06 小结
算法专题目前已日更超过五个月,算法题文章171+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。
以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!
LeetCode算法题-Longest Word in Dictionary(Java实现)的更多相关文章
- LeetCode算法题-Longest Univalue Path(Java实现)
这是悦乐书的第290次更新,第308篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第158题(顺位题号是687).给定二叉树,找到路径中每个节点具有相同值的最长路径的长度 ...
- LeetCode算法题-Longest Harmonious Subsequence(Java实现)
这是悦乐书的第270次更新,第284篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第136题(顺位题号是594).我们定义一个和谐数组是一个数组,其最大值和最小值之间的差 ...
- LeetCode算法题-Longest Continuous Increasing Subsequence(Java实现)
这是悦乐书的第286次更新,第303篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第154题(顺位题号是674).给定未排序的整数数组,找到最长连续增加子序列的长度.例如 ...
- LeetCode算法题-Longest Uncommon Subsequence I(Java实现)
这是悦乐书的第252次更新,第265篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第119题(顺位题号是521).给定一组两个字符串,您需要找到这组两个字符串中最长的不同 ...
- LeetCode算法题-Subdomain Visit Count(Java实现)
这是悦乐书的第320次更新,第341篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第189题(顺位题号是811).像"discuss.leetcode.com& ...
- LeetCode算法题-Letter Case Permutation(Java实现)
这是悦乐书的第315次更新,第336篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第184题(顺位题号是784).给定一个字符串S,将每个字母单独转换为小写或大写以创建另 ...
- LeetCode算法题-Jewels and Stones(Java实现)
这是悦乐书的第313次更新,第334篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第182题(顺位题号是771).字符串J代表珠宝,S代表你拥有的石头.S中的每个字符都是 ...
- LeetCode算法题-Reach a Number(Java实现)
这是悦乐书的第310次更新,第331篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第179题(顺位题号是754).你站在无限数字线的0号位置.在目的地有个target.在 ...
- LeetCode算法题-Self Dividing Numbers(Java实现)
这是悦乐书的第305次更新,第324篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第173题(顺位题号是728).自分割数是一个可被其包含的每个数字整除的数字.例如,12 ...
随机推荐
- ORM(三)QuerySet查询字段操作
这里的环境还是用上次的环境: Django项目:orm_practice app/models.py中有如下几个类: models.py publishing表内容如下: pid name 1 机械工 ...
- 聊聊Unity2018的LWRP和混合光照
0x00 前言 在这篇文章中,我们选择了过去几周Unity官方社区交流群以及UUG社区群中比较有代表性的几个问题,总结在这里和大家进行分享.主要涵盖了** Scripting.Assetsbundle ...
- 自己动手用原生实现 bind/call/apply
大家好!!!注册一年多的第一篇博客. 自我介绍: 本人非计算机专业出身,转行进入前端半年时间,写的东西可能观赏性不强,一起进步吧道友们... 接下来的一段时间, 我都会不定期整理自己理解的js知识点, ...
- Go基础(3)
demo1: package main import "fmt" func print() { for i := 1; i < 10; i++ { for j := 1; j ...
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十二║Vue实战:个人博客第一版(axios+router)
前言 今天正式开始写代码了,之前铺垫了很多了,包括 6 篇基础文章,一篇正式环境搭建,就是为了今天做准备,想温习的小伙伴可以再看看<Vue 基础入门+详细的环境搭建>,内容很多,这里就暂时 ...
- Linux 进程终止后自动重启
/opt/a.sh #! /bin/bash ps -ef | grep python3 a.py | grep -v grep | grep python3 if [ $? -ne 0 ] then ...
- ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目
一.前言 这几年前端的发展速度就像坐上了火箭,各种的框架一个接一个的出现,需要学习的东西越来越多,分工也越来越细,作为一个 .NET Web 程序猿,多了解了解行业的发展,让自己扩展出新的技能树,对自 ...
- BitmapUtil【缩放bitmap以及将bitmap保存成图片到SD卡中】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 用于缩放bitmap以及将bitmap保存成图片到SD卡中 效果图 代码分析 bitmapZoomByHeight(Bitmap s ...
- Kubernetes的DaemonSet(上篇)
背景 静儿作为美团容器化团队HULK的一员,经常需要和Kubernetes(k8s)打交道.第一次登陆node(宿主机)的时候,发现连续登陆几台都看到了Prometheus-Node-Exporter ...
- Vue Mixin 与微信小程序 Mixins 应用
什么是Mixin(混入) Mixin是一种思想,用来实现代码高度可复用性,可以针对属性复制实现代码复用的想法进行一个扩展,就是混入(mixin).混入并不是复制一个完整的对象,而是从多个对象中复制出任 ...