返回单词列表中可以用输入字符的子集组成的所有单词的集合

Posted

技术标签:

【中文标题】返回单词列表中可以用输入字符的子集组成的所有单词的集合【英文标题】:Return a set of all of the words in the word list that can be made with subset of input characters 【发布时间】:2019-06-18 03:12:04 【问题描述】:

我正在解决以下问题,但无法弄清楚如何在 Java 中解决这个问题?

给定一个字符数组,返回一个集合中的所有单词 可以用这些字符的任何子集制作的单词列表。 数组中可能存在重复项,但每个数组索引只能 每个单词使用一次。因此,给定 'o', 'r', 's', 'd', 'o', 'w', 'e' 您可能会返回(除其他外)“word”、“words”和“wood”,但不会 “命令”。

class Finder 

  public void init(Set<String> words) 

  

  public Set<String> find(List<Character> chars) 

  

解决这类问题应该有什么想法?

【问题讨论】:

您需要将words 集分配给Finder 的实例变量(您需要先创建它才能分配它)。在find 方法中,您需要将words 实例变量中的每个单词与chars 参数进行比较,看看是否可以创建它。用每个有效单词填充一个新集合。您将需要循环,我建议您查找称为频率图的东西。 感谢您的建议。我主要对这个In the find method you'll then need to compare each word in the words instance variable to the chars parameter, and see if it can be created 感到困惑。让我再考虑一下。 【参考方案1】:

这是一种可能的方法:

    制作一个计数数组/地图/哈希表来计算每个字符的数量, 所以在你给它的例子中是cnt['o']=2, cnt['r']=1, cnt['s']=1等等

    遍历所有单词并为每个单词创建另一个计数数组结构,我们将其命名为cnt2

    只有在cnt[x] &gt;= cnt2[x] 表示单词的所有不同字母时才能生成单词

    收集所有满足该属性的词放入集合

【讨论】:

【参考方案2】:

这是另一种方法,使用返回布尔值的Collection.remove(Object o)

private static boolean canBeDoneWith(String word, List<Character> chars) 
    List<Character> temp = new ArrayList<>(chars);
    for (char c: word.toCharArray()) 
        if (!temp.remove(Character.valueOf(c))) 
            return false;
        
    
    return true;

方法find变成:

public Set<String> find(List<Character> chars) 
    Set<String> result = new HashSet<>();
    for (String word: words) 
        if (canBeDoneWith(word, chars)) 
            result.add(word);
        
    
    return result;

【讨论】:

以上是关于返回单词列表中可以用输入字符的子集组成的所有单词的集合的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 151. 翻转字符串里的单词

2021-10-16:单词拆分 II。给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。

输入控制

leetcode 151. 颠倒字符串中的单词(进阶版)

leetcode 151. 颠倒字符串中的单词(进阶版)

别人在那看漫画,我在LeetCode刷算法:最后一个单词的长度