java数据结构与算法刷题-----LeetCode524. 通过删除字母匹配到字典里最长单词

发布时间:2023年12月28日
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)
在这里插入图片描述

  1. DP数组及下标含义
  2. 递推公式
  3. dp数组初始化
  4. 遍历顺序
  5. 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;
    }
}

刷题一定要坚持,总结套路,不单单要把题做出来,要举一反三,也要参考别人的思路,学习别人解题的优点,找出你觉得可以优化的点。

  1. 单链表解题思路:双指针、快慢指针、反转链表、预先指针
  1. 双指针:对于单链表而言,可以方便的让我们遍历结点,并做一些额外的事
  2. 快慢指针:常用于找链表中点,找循环链表的循环点,一般快指针每次移动两个结点,慢指针每次移动一个结点。
  3. 反转链表:通常有些题,将链表反转后会更好做,一般选用三指针迭代法,递归的空间复杂度有点高
  4. 预先指针:常用于找结点,比如找倒数第3个结点,那么定义两个指针,第一个指针先移动3个结点,然后两个指针一起遍历,当第一个指针遍历完成,第二个指针指向的结点就是要找的结点
  1. 数组解题思路:双指针、三指针,下标标记
  1. 双指针:多用于减少时间复杂度,快速遍历数组
  2. 三指针:多用于二分查找,分为中间指针,左和右指针
  3. 下标标记:常用于在数组范围内找东西,而不想使用额外的空间的情况,比如找数组长度为n,元素取值范围为[1,n]的数组中没有出现的数字,遍历每个元素,然后将对应下标位置的元素变为负数或者超出[1,n]范围的正数,最后没有发生变化的元素,就是缺少的值。
文章来源:https://blog.csdn.net/grd_java/article/details/135276047
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。