[非重复型打乱匹配问题+状压]Count Words Obtained After Adding a Letter

Description

You are given two 0-indexed arrays of strings startWords and targetWords. Each string consists of lowercase English letters only.

For each string in targetWords, check if it is possible to choose a string from startWords and perform a conversion operation on it to be equal to th

at from targetWords.

The conversion operation is described in the following two steps:

Append any lowercase letter that is not present in the string to its end.
For example, if the string is "abc", the letters 'd', 'e', or 'y' can be added to it, but not 'a'. If 'd' is added, the resulting string will be "abcd".
Rearrange the letters of the new string in any arbitrary order.
For example, "abcd" can be rearranged to "acbd", "bacd", "cbda", and so on. Note that it can also be rearranged to "abcd" itself.
Return the number of strings in targetWords that can be obtained by performing the operations on any string of startWords.

Note that you will only be verifying if the string in targetWords can be obtained from a string in startWords by performing the operations. The strings in startWords do not actually change during this process.

Analysis

  • 可以避免排序O(nlogn)再匹配带来的时间复杂度问题

  • 用32位中的26位即可

Source Code

class Solution {
public:
    int wordCount(vector<string>& startWords, vector<string>& targetWords) {
        // 将 word 转化为表示包含字母状态的二进制整数
        auto mask = [](string& word) -> int {
            int res = 0;
            for (char ch: word)
                res |= 1 << (ch - 'a');
            return res;
        };

        unordered_set<int> masks;   // 所有可以获得的状态
        for (string& start: startWords) {
            // 遍历初始单词,根据其状态值构造所有可以获得的状态
            int msk = mask(start);
            for (int i = 0; i < 26; ++i)
                if (((msk >> i) & 1) == 0)
                    masks.insert(msk | (1 << i));
        }
        int cnt = 0;   // 可以获得的单词数
        for (string& target: targetWords)
            if (masks.count(mask(target)))
                ++cnt;
        return cnt;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值