893. Groups of Special-Equivalent Strings 思路比较典型的一个题目

You are given an array A of strings.

move onto S consists of swapping any two even indexed characters of S, or any two odd indexed characters of S.

Two strings S and T are special-equivalent if after any number of moves onto SS == T.

For example, S = "zzxy" and T = "xyzz" are special-equivalent because we may make the moves "zzxy" -> "xzzy" -> "xyzz" that swap S[0] and S[2], then S[1]and S[3].

Now, a group of special-equivalent strings from A is a non-empty subset of A such that:

  1. Every pair of strings in the group are special equivalent, and;
  2. The group is the largest size possible (ie., there isn't a string S not in the group such that S is special equivalent to every string in the group)

Return the number of groups of special-equivalent strings from A.

 

Example 1:

Input: ["abcd","cdab","cbad","xyzz","zzxy","zzyx"]
Output: 3
Explanation: 
One group is ["abcd", "cdab", "cbad"], since they are all pairwise special equivalent, and none of the other strings are all pairwise special equivalent to these.

The other two groups are ["xyzz", "zzxy"] and ["zzyx"].  Note that in particular, "zzxy" is not special equivalent to "zzyx".

Example 2:

Input: ["abc","acb","bac","bca","cab","cba"]
Output: 3

 

Note:

  • 1 <= A.length <= 1000
  • 1 <= A[i].length <= 20
  • All A[i] have the same length.
  • All A[i] consist of only lowercase letters.

我觉得这个题目蛮好的,至少是一类题目的思路。

关键在于理清楚,一个字符串的偶数位和奇数位分别一样,不管位置如何,就可以是equivalent。

因此,万宗归一,对每个字符串s,奇数和偶数分别拎出来,只要其从小到大排列后,再合成字符串ss,对于所有equivalent的字符串,其归一后的ss是一样的。

用了std::map,归一后的字符串ss为key,原始做value。

代码如下,

class Solution {
public:
    int numSpecialEquivGroups(vector<string>& A) {
        std::map<string, vector<string>> res;
        if(A.size() == 0)
            return 0;
        for(auto s : A)
        {
            vector<char> charEven;
            vector<char> charOdd;
            for(int i = 0; i < s.size(); i++)
            {
                if(i & 1)
                {
                    charOdd.push_back(s[i]);
                }
                else
                {
                    charEven.push_back(s[i]);
                }
            }
            if(charEven.size() >0)
                std::sort(charEven.begin(), charEven.end());
            if(charOdd.size() >0)
                std::sort(charOdd.begin(), charOdd.end());

            string ss;
            int i = 0;
            for(i = 0; i < charEven.size() and i < charOdd.size(); i++)
            {
                ss.append(1, charEven[i]);
                ss.append(1, charOdd[i]);
            }
            if(i < charEven.size())
                ss.append(1, charEven[i]);
            if(i < charOdd.size())
                ss.append(1, charOdd[i]);

            if(res.find(ss) != res.end())
                res[ss].push_back(s);
            else
                res[ss] = vector<string>{s};
        }
        return res.size();
    }
};

执行效果

Runtime: 32 ms, faster than 15.56% of C++ online submissions for Groups of Special-Equivalent Strings.

Memory Usage: 11.4 MB, less than 50.00% of C++ online submissions forGroups of Special-Equivalent Strings.

还凑合,不是吗?

看看别人的改进,其中一个思路是不重新合并新的ss,而是用vector<char> odd(26, 0)和vector<char> even(26,0),将奇偶位置上的字符串分别映射过去,作为key,直接copy一下别人的代码吧,侵权告知啦。

class Solution {
public:
    int numSpecialEquivGroups(vector<string>& A) {
        map<pair<vector<int>,vector<int>>,vector<string>>m;
        int n = A.size();
        for(int i=0;i<n;i++){
            vector<int>even(26,0);
            vector<int>odd(26,0);
            for(int j=0;j<A[i].length();j++){
                if(j%2==0)
                    even[A[i][j]-'a']++;
                else
                    odd[A[i][j]-'a']++;
            }
            m[{even,odd}].push_back(A[i]);
        }
        return m.size();
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值