题目:

给你一个字符串 s 和一个字符串数组 dictionary ,找出并返回 dictionary 中最长的字符串,该字符串可以通过删除 s 中的某些字符得到。

如果答案不止一个,返回长度最长且字母序最小的字符串。如果答案不存在,则返回空字符串。

示例 1:

输入:s = "abpcplea", dictionary = ["ale","apple","monkey","plea"]
输出:"apple"
示例 2:

输入:s = "abpcplea", dictionary = ["a","b","c"]
输出:"a"

提示:

1 <= s.length <= 1000
1 <= dictionary.length <= 1000
1 <= dictionary[i].length <= 1000
s 和 dictionary[i] 仅由小写英文字母组成

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-word-in-dictionary-through-deleting
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

一、排序+双指针

1.首先将字符串数组dictionary中的每个字符串进行排序,如果字符串长度不相等,则按照长度降序排序,如果字符串相等,则按字符升序排序;

2.遍历排好序后的dictionary中每个字符串,定义两个指针 i 和 j ,分别指向字符串 s 和 dictionary中每个字符串 s1的起始位置,如果

s.charAt(i) == s1.charAt(j) ,则两个指针都向后移一位,否则,就仅让 指向 s 的指针 i 后移,继续判断;
3.最终,如果 j == 当前s1的长度,说明该字符串匹配成功,不需要再进行后续匹配,直接返回即可,如果整个遍历匹配都不成功,直接返回空字符串 ""。
代码:

二、动态规划

1.先使用动态规划对 s 中的字符位置进行预处理,设s的字符串长度为n,建立一个 n+1*26 大小的矩阵,初始化二维数组的最后一行dp[n][i] 都为n,从后往前填充数组,其他每个位置上的值代表s中每个字符第一次出现的位置;

2.设定一个标志位表示是否匹配成功,初始值为true,遍历字符数组dictionary中每个字符串的每个字符,如果当前值为初始化值n,表示不匹配,

如果查找到,,则从字符串s的下一位继续匹配;
3.如果最终有多个值匹配,则选择dictionary中最长的字符串,如果存在两个匹配的字符串相等,则选择字母序列最小的返回即可。
 
代码:
 1 class Solution {
2 public String findLongestWord(String s, List<String> dictionary) {
3 int n = s.length();
4 int[][] dp = new int[n+1][26];
5 //初始化二维数组最后一行
6 for(int i = 0; i < 26; i++){
7 dp[n][i] = n;
8 }
9 //动态填充二维数组,从后往前遍历
10 for(int i = n-1; i >= 0; i--){
11 for(int j = 0; j < 26; j++){
12 //如果当前字符与26字母中的一个相同,则当前行号就为当前位置的值
13 if(s.charAt(i) == (char)(j + 'a')){
14 dp[i][j] = i;
15 }else{
16 //如果不同,则将下一行的值给当前行
17 dp[i][j] = dp[i + 1][j];
18 }
19 }
20 }
21 String res = "";
22 //开始匹配
23 for(String d1 : dictionary){
24 //设定一个标志位表示是否匹配成功,初始值为匹配
25 boolean match = true;
26 int j = 0;
27 //遍历字符数组中每个字符串的每个字符
28 for(int i = 0; i < d1.length(); i++){
29 //如果当前值为初始化值,表示不匹配
30 if(dp[j][d1.charAt(i) - 'a'] == n){
31 match = false;
32 break;
33 }
34 //如果查找到,,则从s的下一位继续匹配
35 j = dp[j][d1.charAt(i) - 'a'] + 1;
36 }
37 if(match){
38 //在匹配的条件下,如果长度大或者在长度相等的情况下选择字母序小的,
39 if(d1.length() > res.length() || (d1.length() == res.length() && d1.compareTo(res) < 0)){
40 res = d1;
41 }
42 }
43 }
44 return res;
45
46 }
47 }

小知识:

1.以下两种写法是一个意思,都是将字符数组中长度不等的每个字符串进行升序排序,长度相等的按字母顺序降序排序。

Collections.sort(list, new Comparator<>()):

第一个参数:需要排序的list

第二个参数:比较器,实现Comparator接口的类,返回一个int型的值,就相当于一个标志,告诉sort方法按什么顺序来对list进行排序。Comparator是个接口,可重写compare()及equals()这两个方法,用于比较功能。

  • compare(a,b)方法:根据第一个参数小于、等于或大于第二个参数分别返回负整数(升序)、零(不变)或正整数(降序)。

升序: list.sort((a,b)->a-b);    或者    list.sort((a,b)->a.compareTo(b));

降序:list.sort((a,b)->b-a);     或者    list.sort((a,b)->b.compareTo(a));

  • equals(obj)方法:仅当指定的对象也是一个 Comparator,并且强行实施与此 Comparator 相同的排序时才返回 true。

a.compareTo(b) 来“比较a和b的大小”,方便记忆为"x-y"。若返回“负数”,意味着“a比b小”;返回“零”,意味着“a等于b”;返回“正数”,意味着“a大于b”。

  • *升序排的话就是第一个参数.compareTo(第二个参数);
  • *降序排的话就是第二个参数.compareTo(第一个参数);

// 1.
Collections.sort(dictionary, new Comparator<String>() {
public int compare(String a, String b) {
if (a.length() != b.length()) {
return b.length() - a.length();
} else {
return a.compareTo(b);
}
}
});
//2.
Collections.sort(dictionary, (a,b)->{
if(a.length() != b.length())
return b.length() - a.length();
return a.compareTo(b);
});

2.空字符串("")和 null 和 空格字符串("  ")的区别:

1  string str1 = "";     //空字符串,分配了内存,分配了一个空间     str1.length() 等于 0
2 string str2 = null; //NULL
3 string str3 = " "; //空格串,分配了内存,分配了一个空间 str2.length() 等于 1

力扣524(java)-通过删除字母匹配到字典里最长单词(中等)的更多相关文章

  1. Java实现 LeetCode 524 通过删除字母匹配到字典里最长单词(又是一道语文题)

    524. 通过删除字母匹配到字典里最长单词 给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到.如果答案不止一个,返回长度最长且字典顺序最小的字符 ...

  2. 524. 通过删除字母匹配到字典里最长单词 (Medium)

    问题描述 524. 通过删除字母匹配到字典里最长单词 (Medium) 给你一个字符串 s 和一个字符串数组 dictionary ,找出并返回 dictionary 中最长的字符串,该字符串可以通过 ...

  3. leetcode.双指针.524通过删除字母匹配到字典里最长单词-Java

    1. 具体题目 给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到.如果答案不止一个,返回长度最长且字典顺序最小的字符串.如果答案不存在,则返回空 ...

  4. [Swift]LeetCode524. 通过删除字母匹配到字典里最长单词 | Longest Word in Dictionary through Deleting

    Given a string and a string dictionary, find the longest string in the dictionary that can be formed ...

  5. 【LeetCode】524-通过删除字母匹配到字典里最长单词

    题目描述 给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到.如果答案不止一个,返回长度最长且字典顺序最小的字符串.如果答案不存在,则返回空字符串 ...

  6. leetcode 524. Longest Word in Dictionary through Deleting 通过删除字母匹配到字典里最长单词

    一.题目大意 https://leetcode.cn/problems/longest-word-in-dictionary-through-deleting 给你一个字符串 s 和一个字符串数组 d ...

  7. 力扣(LeetCode)删除排序链表中的重复元素II 个人题解

    给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 思路和上一题类似(参考 力扣(LeetCode)删除排序链表中的重复元素 个人题解)) 只不过这里需要用到一个前 ...

  8. 力扣——remove element(删除元素) python实现

    题目描述: 中文: 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) ...

  9. 力扣(LeetCode)删除排序链表中的重复元素 个人题解

    给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 这题思路比较简单,同样是快慢针的思路. 用一个整数类型val对应最新的只出现过一次的那个值, 如果节点的下一个节点的值和这个对应则不做别 ...

  10. 力扣—Remove Nth Node From End of List(删除链表的倒数第N个节点) python实现

    题目描述: 中文: 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二 ...

随机推荐

  1. Prometheus四种指标及PromQL实例

    Prometheus四种主要的指标类型包括Counter.Gauge.Histogram和Summary,以及相应的PromQL实例如下: Counter(计数器) 作用:只增不减的计数器,常用于记录 ...

  2. Prometheus常用exporter及其常用监控指标

    node-exporter常用监控指标 CPU相关指标: node_cpu_seconds_total{mode="idle"}:CPU空闲时间(秒)的总和.这是评估CPU使用率的 ...

  3. 8、Linux CentOS 安装.Net Core 3.1

    1.添加密钥 将 Microsoft 包签名密钥添加到受信任密钥列表,并添加 Microsoft 包存储库. 打开终端并运行以下命令: sudo rpm -Uvh https://packages.m ...

  4. [Raspberry Pi]树莓派多线程下串口收发数据

    [Raspberry Pi]树莓派多线程下串口收发数据 鼠鼠用的是python开发树莓派,因为python是最优美的语言! 少废话,直接上代码: import threading import ser ...

  5. Spring Boot框架中使用Jackson的处理总结

    1.前言 通常我们在使用Spring Boot框架时,如果没有特别指定接口的序列化类型,则会使用Spring Boot框架默认集成的Jackson框架进行处理,通过Jackson框架将服务端响应的数据 ...

  6. Swift Structured Concurrency

    异步函数 异步函数概念 异步和并发是两个不同的概念,并发(Concurrency)是指多个任务同时执行,这里的同时不是严格意义上的同一时刻,而是在稍大时间粒度上,多个任务可以同时推进,并发的实现可以是 ...

  7. [Oracle]细节、经验

    [版权声明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/131054454 出自[进步* ...

  8. vscode插件设置——Golang开发环境配置

    适用读者: Go初学者, 到这里, 你应该是处于已经完成了 go 的安装之后, 准备写个 "Hello Gopher" 之前. 本篇力求给初学者-未来的Gopher 们 一个正确的 ...

  9. Scala变量和常量的声明

    标示符的命名规则 1. 字母或下划线开头 2. 以操作符开头,且只包含操作符(+ - * / # !等) 3. 用反引号`....`包括的任意字符串,即使是 Scala 关键字(39 个)也可以• p ...

  10. getElementsByName和getElementById的区别

    1 清洗表名: <input type="text" name="fileName"/><br/> 1 var fileName = d ...