leetcod - 524. Longest Word in Dictionary through Deleting【字符串匹配 + 双指针 + Comparator + java高效函数】

题目

Given a string and a string dictionary, find the longest string in the dictionary that can be formed by deleting some characters of the given string. If there are more than one possible results, return the longest word with the smallest lexicographical order. If there is no possible result, return the empty string.

Example 1:

Input:
s = "abpcplea", d = ["ale","apple","monkey","plea"]

Output: 
"apple"

Example 2:

Input:
s = "abpcplea", d = ["a","b","c"]

Output: 
"a"

Note:

  1. All the strings in the input will only contain lower-case letters.
  2. The size of the dictionary won't exceed 1,000.
  3. The length of all the strings in the input won't exceed 1,000.

题意

给定一个字符串s和一个字符串字典,找出通过删除s中的一些字母生成字典中最长的字符串。如果有不止一个结果,那么返回字典顺序最小的字符串。如果没有结果,那么返回空字符。

分析及解答

解法1:(我的答案)

  • 【java基础知识:Comparator使用】对于容器(如:list)中内容的排序。
  • 【贪心算法】(对于字典中的每个单词),与s相比,从最左处开始匹配。
  • 【指针移动规则】出现相同字符,同时后移;否则 只 s 的指针后移。

public class Solution {
   
	public static class ComparatorByLength implements Comparator { // 定义比较器

		@Override
		public int compare(Object o1, Object o2) {
			String s1 = (String) o1;
			String s2 = (String) o2;

			int temp = s1.length() - s2.length();

			return temp == 0 ? s1.compareTo(s2) : -temp;
		}
	}
	
    public String findLongestWord(String s, List<String> d) {
    	if(s == null || d == null || s.length() == 0 || d.size() == 0){
    		return "";
    	}
    	ComparatorByLength cl = new ComparatorByLength();
        Collections.sort(d,cl); 
        for(String str : d){
        	int p1 = 0;
        	int p2 = 0;
        	while(p1 < s.length() && p2 < str.length()){
        		if(s.charAt(p1) == str.charAt(p2)){
        			p1++;
        			p2++;
        		}else{
        			p1++;
        		}
        	}
        	if(p2 == str.length()){
        		return str;
        	}
        }
        return "";
    }
}

解法1.1:(简化代码,但效率不高)

public String findLongestWord(String s, List<String> d) {
    Collections.sort(d, (a,b) -> a.length() != b.length() ? -Integer.compare(a.length(), b.length()) :  a.compareTo(b));
    for (String dictWord : d) {
        int i = 0;
        for (char c : s.toCharArray()) 
            if (i < dictWord.length() && c == dictWord.charAt(i)) i++;
        if (i == dictWord.length()) return dictWord;
    }
    return "";
}

解法2:(非常高效)

关于indexOf :

s.indexOf("c", 3) :表示// 从第四个字符位置开始往后继续查找,包含当前位置

public class Solution {
    public String findLongestWord(String s, List<String> d) {
        String result = "";
        for (String str : d) {
            if (isBetter(str, result) && isSubstring(str, s)) {
                result = str;
            }
        }
        return result;
    }
    
    private boolean isBetter(String candidate, String longest) {
        return candidate.length() > longest.length() ||
                (candidate.length() == longest.length() && candidate.compareTo(longest) < 0);
    }
    
    private boolean isSubstring(String candidate, String target) {
        int start = -1;
        for (int i = 0; i < candidate.length(); i++) {
            start = target.indexOf(candidate.charAt(i), start+1);//indexOf非常高效
            if (start < 0) {
                return false;
            }
        }
        return true;
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值