Skip to content

Latest commit

 

History

History
180 lines (139 loc) · 5.13 KB

File metadata and controls

180 lines (139 loc) · 5.13 KB
comments difficulty edit_url tags
true
中等
数组
哈希表
字符串

English Version

题目描述

对字符串进行 “移位” 的操作:

  • 右移:将字符串中每个字母都变为其在字母表中 后续 的字母,其中用 'a' 替换 'z'。比如,"abc" 能够右移为 "bcd""xyz" 能够右移为 "yza"
  • 左移:将字符串中每个字母都变为其在字母表中 之前 的字母,其中用 'z' 替换 'a'。比如,"bcd" 能够右移为 "abc""yza" 能够右移为 "xyz"

我们可以不断地向两个方向移动字符串,形成 无限的移位序列

  • 例如,移动 "abc" 来形成序列:... <-> "abc" <-> "bcd" <-> ... <-> "xyz" <-> "yza" <-> ... <-> "zab" <-> "abc" <-> ...

给定一个字符串数组 strings,将属于相同移位序列的所有 strings[i] 进行分组。你可以以 任意顺序 返回答案。

 

示例 1:

输入:strings = ["abc","bcd","acef","xyz","az","ba","a","z"]

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

 

示例 2:

输入:strings = ["a"]

输出:[["a"]]

 

提示:

  • 1 <= strings.length <= 200
  • 1 <= strings[i].length <= 50
  • strings[i] 只包含小写英文字母。

解法

方法一:哈希表

我们用一个哈希表 $g$ 来存储每个字符串移位后且首位为 'a' 的字符串。即 $g[t]$ 表示所有字符串移位后字符串为 $t$ 的字符串集合。

我们遍历每个字符串,对于每个字符串,我们计算其移位后的字符串 $t$,然后将其加入到 $g[t]$ 中。

最后,我们将 $g$ 中的所有值取出来,即为答案。

时间复杂度 $O(L)$,空间复杂度 $O(L)$,其中 $L$ 为所有字符串的长度之和。

Python3

class Solution:
    def groupStrings(self, strings: List[str]) -> List[List[str]]:
        g = defaultdict(list)
        for s in strings:
            diff = ord(s[0]) - ord("a")
            t = []
            for c in s:
                c = ord(c) - diff
                if c < ord("a"):
                    c += 26
                t.append(chr(c))
            g["".join(t)].append(s)
        return list(g.values())

Java

class Solution {
    public List<List<String>> groupStrings(String[] strings) {
        Map<String, List<String>> g = new HashMap<>();
        for (var s : strings) {
            char[] t = s.toCharArray();
            int diff = t[0] - 'a';
            for (int i = 0; i < t.length; ++i) {
                t[i] = (char) (t[i] - diff);
                if (t[i] < 'a') {
                    t[i] += 26;
                }
            }
            g.computeIfAbsent(new String(t), k -> new ArrayList<>()).add(s);
        }
        return new ArrayList<>(g.values());
    }
}

C++

class Solution {
public:
    vector<vector<string>> groupStrings(vector<string>& strings) {
        unordered_map<string, vector<string>> g;
        for (auto& s : strings) {
            string t;
            int diff = s[0] - 'a';
            for (int i = 0; i < s.size(); ++i) {
                char c = s[i] - diff;
                if (c < 'a') {
                    c += 26;
                }
                t.push_back(c);
            }
            g[t].emplace_back(s);
        }
        vector<vector<string>> ans;
        for (auto& p : g) {
            ans.emplace_back(move(p.second));
        }
        return ans;
    }
};

Go

func groupStrings(strings []string) [][]string {
	g := make(map[string][]string)
	for _, s := range strings {
		t := []byte(s)
		diff := t[0] - 'a'
		for i := range t {
			t[i] -= diff
			if t[i] < 'a' {
				t[i] += 26
			}
		}
		g[string(t)] = append(g[string(t)], s)
	}
	ans := make([][]string, 0, len(g))
	for _, v := range g {
		ans = append(ans, v)
	}
	return ans
}