java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 |
---|
法一:双指针,具体看代码注释
class Solution {
//1. s中删除任意个字符,从左到右,可以完全匹配字典中的某个值,就是我们要找的
//2. 如果有多个我们要找的,返回最长的
//3. 如果有多个长度相等的,返回较大的(字母序),通过A.compareTo(B)即可比较A是否比B大
//4. compareTo有3种值,-1,0,1. -1表示A小于B。0表示相等,1表示A大于B
public String findLongestWord(String s, List<String> dictionary) {
String res = "";//最终结果字符串
for(String item: dictionary){//遍历字典
int left = 0, right = 0;//双指针,一个指向主字符串s,另一个指向字典中的值item
while(left<item.length() && right<s.length()){//如果某一个遍历完,就结束
if(item.charAt(left) == s.charAt(right)) left++;//若匹配成功,item进行下一个比较
right ++;//无论如何s都需要向下遍历,因为我们可以删除任意个s中字符
}
if(left == item.length()){//如果item完全被匹配,就是我们要找的
//然后判断是否比上一个符合条件的更长,或者长度相等
if(item.length()>res.length() || //若它的长度更长,直接让res执行它
(item.length() == res.length() && item.compareTo(res) <0))//若长度相等,判断是否item字母序更小
res = item;
}
}
return res;
}
}
法二:动态规划(TODO)
- DP数组及下标含义
- 递推公式
- dp数组初始化
- 遍历顺序
- dp数组打印
class Solution {
public String findLongestWord(String s, List<String> dictionary) {
int m = s.length();
int[][] f = new int[m + 1][26];
Arrays.fill(f[m], m);
for (int i = m - 1; i >= 0; --i) {
for (int j = 0; j < 26; ++j) {
if (s.charAt(i) == (char) ('a' + j)) {
f[i][j] = i;
} else {
f[i][j] = f[i + 1][j];
}
}
}
String res = "";
for (String t : dictionary) {
boolean match = true;
int j = 0;
for (int i = 0; i < t.length(); ++i) {
if (f[j][t.charAt(i) - 'a'] == m) {
match = false;
break;
}
j = f[j][t.charAt(i) - 'a'] + 1;
}
if (match) {
if (t.length() > res.length() || (t.length() == res.length() && t.compareTo(res) < 0)) {
res = t;
}
}
}
return res;
}
}
刷题一定要坚持,总结套路,不单单要把题做出来,要举一反三,也要参考别人的思路,学习别人解题的优点,找出你觉得可以优化的点。
- 单链表解题思路:双指针、快慢指针、反转链表、预先指针
- 双指针:对于单链表而言,可以方便的让我们遍历结点,并做一些额外的事
- 快慢指针:常用于找链表中点,找循环链表的循环点,一般快指针每次移动两个结点,慢指针每次移动一个结点。
- 反转链表:通常有些题,将链表反转后会更好做,一般选用三指针迭代法,递归的空间复杂度有点高
- 预先指针:常用于找结点,比如找倒数第3个结点,那么定义两个指针,第一个指针先移动3个结点,然后两个指针一起遍历,当第一个指针遍历完成,第二个指针指向的结点就是要找的结点
- 数组解题思路:双指针、三指针,下标标记
- 双指针:多用于减少时间复杂度,快速遍历数组
- 三指针:多用于二分查找,分为中间指针,左和右指针
- 下标标记:常用于在数组范围内找东西,而不想使用额外的空间的情况,比如找数组长度为n,元素取值范围为[1,n]的数组中没有出现的数字,遍历每个元素,然后将对应下标位置的元素变为负数或者超出[1,n]范围的正数,最后没有发生变化的元素,就是缺少的值。