[LeetCode] 249. Group Shifted Strings 分组偏移字符串

Given a string, we can "shift" each of its letter to its successive letter, for example: "abc" -> "bcd". We can keep "shifting" which forms the sequence:

"abc" -> "bcd" -> ... -> "xyz"

Given a list of strings which contains only lowercase alphabets, group all strings that belong to the same shifting sequence.

For example, given: ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"]
Return:

[
  ["abc","bcd","xyz"],
  ["az","ba"],
  ["acef"],
  ["a","z"]
]

Note: For the return value, each inner list's elements must follow the lexicographic order.

一个字符串可以通过偏移变成另一个字符串,比如 ‘abc’ –> ‘bcd’ (所有字母右移一位),把可通过偏移转换的字符串归为一组。给定一个 String 数组,返回分组结果。

解法:将每个字符串都转换成与字符串首字符ASCII码值差的字符串,比如:'abc'就转换成'012','bcd'转换成了'012',两个就是同组的偏移字符串。用Hashmap来统计,key就是转换后的数字字符串,value是所有可以转换成此key的字符串集合。

注意:这个差值可能是负的,说明后面的字符比前面的小,此时加上26。

Java:

class Solution {
    public List<List<String>> groupStrings(String[] strings) {
        List<List<String>> result = new ArrayList<List<String>>();
        HashMap<String, ArrayList<String>> map 
                        = new HashMap<String, ArrayList<String>>();

        for(String s: strings){
            char[] arr = s.toCharArray();
            if(arr.length>0){
                int diff = arr[0]-'a';
                for(int i=0; i<arr.length; i++){
                    if(arr[i]-diff<'a'){
                       arr[i] = (char) (arr[i]-diff+26);
                    }else{
                       arr[i] = (char) (arr[i]-diff); 
                    }

                }
            }  

            String ns = new String(arr);
            if(map.containsKey(ns)){
                map.get(ns).add(s);
            }else{
                ArrayList<String> al = new ArrayList<String>();
                al.add(s);
                map.put(ns, al);
            }
        }

        for(Map.Entry<String, ArrayList<String>> entry: map.entrySet()){
            Collections.sort(entry.getValue());
        }

        result.addAll(map.values());

        return result;
    }
}

Python: Time: O(nlogn), Space: O(n)

import collections

class Solution:
    # @param {string[]} strings
    # @return {string[][]}
    def groupStrings(self, strings):
        groups = collections.defaultdict(list)
        for s in strings:  # Grouping.
            groups[self.hashStr(s)].append(s)

        result = []
        for key, val in groups.iteritems():
            result.append(sorted(val))

        return result

    def hashStr(self, s):
        base = ord(s[0])
        hashcode = ""
        for i in xrange(len(s)):
            if ord(s[i]) - base >= 0:
                hashcode += unichr(ord('a') + ord(s[i]) - base)
            else:
                hashcode += unichr(ord('a') + ord(s[i]) - base + 26)
        return hashcode

C++:  

class Solution {
public:
    vector<vector<string>> groupStrings(vector<string>& strings) {
        vector<vector<string> > res;
        unordered_map<string, multiset<string>> m;
        for (auto a : strings) {
            string t = "";
            for (char c : a) {
                t += to_string((c + 26 - a[0]) % 26) + ",";
            }
            m[t].insert(a);
        }
        for (auto it = m.begin(); it != m.end(); ++it) {
            res.push_back(vector<string>(it->second.begin(), it->second.end()));
        }
        return res;
    }
};  

  

类似题目:

[LeetCode] 49. Group Anagrams 分组变位词 

[LeetCode] 300. Longest Increasing Subsequence 最长递增子序列

 

All LeetCode Questions List 题目汇总

 

posted @ 2018-04-06 13:51  轻风舞动  阅读(1171)  评论(0编辑  收藏  举报