1048. Longest String Chain

本文解析了LeetCode 1048题“最长单词链”的解决方案,详细介绍了如何通过动态规划和哈希映射的方法,寻找给定单词列表中可能形成的最长单词链。文章强调了理解题目中“前驱”概念的重要性,即仅通过添加一个字母形成新的单词。

题目:

Given a list of words, each word consists of English lowercase letters.

Let's say word1 is a predecessor of word2 if and only if we can add exactly one letter anywhere in word1 to make it equal to word2.  For example, "abc" is a predecessor of "abac".

word chain is a sequence of words [word_1, word_2, ..., word_k] with k >= 1, where word_1 is a predecessor of word_2word_2 is a predecessor of word_3, and so on.

Return the longest possible length of a word chain with words chosen from the given list of words.

 

Example 1:

Input: ["a","b","ba","bca","bda","bdca"]
Output: 4
Explanation: one of the longest word chain is "a","ba","bda","bdca".

解法:

这题看上去和LIS差不多,但是要注意题意里的predecessor的含义是,only add one letter。清楚了这一点,就可以分析出状态转移方程。

对于第n个字符串来说,需要做的是遍历该字符串中的每一个char,去掉该char之后组成一个新字符串。将这个新字符串与前n-1个字符串比较,如果能对应上,就在对应上的基础上+1。

这里也可以用传统的dp方法,创建一个dp数组,每次循环更新。但是由于需要不停地比对字符串,循环过多。所以可以采用HASHMAP来存储。需要注意的是,在hashmap取对应的key时,使用getOrdefault方法,表示取不到该字符串时返回长度0。

 

    /*
     * 1048. Longest String Chain
     * https://leetcode.com/problems/longest-string-chain/
     * 看上去和LIS差不多。注意题意是only add exactly one letter!!
     */
    
    public int longestStrChain(String[] words) {
        if(words == null || words.length == 0){
            return 0;
        }
        int res = 0;
        HashMap<String,Integer> dp = new HashMap<>();
        //注意这种写法!!
        Arrays.sort(words,(a,b) -> a.length() - b.length());
        for(int i = 0; i < words.length ; i++) {
        	int max = 0;
        	for(int j = 0 ;j < words[i].length();j++) {
        		String prev = words[i].substring(0,j) + words[i].substring(j+1);
        		max = Math.max(max, dp.getOrDefault(prev, 0) + 1);
                //System.out.println(prev + "->" + words[i] );
        	}
        	dp.put(words[i], max);
        	res = Math.max(res, max);
        }
        return res;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值