LeetCode个人刷题笔记——249.移位字符串分组

题目

给定一个字符串,对该字符串可以进行 “移位” 的操作,也就是将字符串中每个字母都变为其在字母表中后续的字母,比如:“abc” -> “bcd”。这样,我们可以持续进行 “移位” 操作,从而生成如下移位序列:“abc” -> “bcd” -> … -> “xyz” 给定一个包含仅小写字母字符串的列表,将该列表中所有满足 “移位” 操作规律的组合进行分组并返回。

示例:
输入:[“abc”, “bcd”, “acef”, “xyz”, “az”, “ba”, “a”, “z”]
输出:
[
[“abc”,“bcd”,“xyz”],
[“az”,“ba”],
[“acef”],
[“a”,“z”]
]
解释:可以认为字母表首尾相接,所以 ‘z’ 的后续为 ‘a’,所以 [“az”,“ba”] 也满足 “移位” 操作规律。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/group-shifted-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

根据题目意思,处于同一个序列的string有一个前提条件,就是长度相同。如abc,xyz。第二个条件,两个不同的string中其两个字符之间的差值相同。
因此,同一个序列的字符串,都可以经过统一移位操作变成开头为‘a’的相同字符串。利用暴力法,对string数组进行双层遍历,大循环每次取一个string,将其移位到与’a’对齐,从这个string后开始内循环,找到长度相同的string时,判断是否可以通过移位统一,统一就入列。在循环中,可以利用一个book数组或者哈希表进行访问标记,用过的string之后不再使用。这样做虽然利用了hash,但是并没有换来明显的时间提升,依然是O(n^2),不够优雅。下面来看看hash和string的米奇妙妙屋操作。
对string数组进行遍历,每一次将string的开头与‘a’对齐,在hashmap中查找移位后的string是否存在,如果存在,说明有和该string的同一序列,则存储到相应的位置,否则,标记hashmap,重开一个序列。

class Solution {
public:
    vector<vector<string>> groupStrings(vector<string>& strings) {
        vector<vector<string>> res;
        int l=strings.size();
        if(l==0)
            return res;
        unordered_map<string,int> book;
        int index=0;
        for(int i=0;i<l;i++){
            string ss(strings[i]);
            //向a对齐
            if(ss[0]!='a'){//不是a,需要对齐
                int s=ss.size();
                for(int j=1;j<s;j++){
                    ss[j]=(ss[j]-ss[0]+26)%26+'a';
                }
                ss[0]='a';
            }
            if(book.count(ss)!=0){//有统一序列
                res[book[ss]].push_back(strings[i]);
                continue;
            }
            book[ss]=index++;
            res.push_back({strings[i]});
        }
        return res;
    }
};

你可能感兴趣的:(LeetCode个人刷题笔记——249.移位字符串分组)