你將得到一個字符串數組 A
。
如果經過任意次數的移動,S == T,那麼兩個字符串 S
和 T
是特殊等價的。
一次移動包括選擇兩個索引 i
和 j
,且 i%2 == j%2
,並且交換 S[j]
和 S [i]
。
現在規定,A
中的特殊等價字符串組是 A
的非空子集 S
,這樣不在 S
中的任何字符串與 S
中的任何字符串都不是特殊等價的。
返回 A
中特殊等價字符串組的數量。
示例 1:
輸入:["a","b","c","a","c","c"] 輸出:3 解釋:3 組 ["a","a"],["b"],["c","c","c"]
示例 2:
輸入:["aa","bb","ab","ba"] 輸出:4 解釋:4 組 ["aa"],["bb"],["ab"],["ba"]
示例 3:
輸入:["abc","acb","bac","bca","cab","cba"] 輸出:3 解釋:3 組 ["abc","cba"],["acb","bca"],["bac","cab"]
示例 4:
輸入:["abcd","cdab","adcb","cbad"] 輸出:1 解釋:1 組 ["abcd","cdab","adcb","cbad"]
提示:
1 <= A.length <= 1000
1 <= A[i].length <= 20
- 所有
A[i]
都具有相同的長度。 - 所有
A[i]
都只由小寫字母組成。
Review:
這個題目描述花了好久纔看懂...
首先明白一點,兩個字符串等價其實就是兩個字符串的偶數位和奇數位各個字母種類和個數一樣
ambn 和 bnam 這兩個等價的原因就是 奇數位都由ab組成,偶數位都由mn組成
時間複雜度最低的做法就是用hashset,將等價字符串總結抽象成相同的值
比如 ambn 可以用 "1a1b-1m1n"來代替,其意思就是 奇數位1個a1個b,偶數位1個m一個n
根據string在hashset中的不可重複性來去掉等價的值,只留下一組
我看到了6ms的是用這種方式來做的,也是很不錯的速度 99.8%
但是要想更快,可以使用類似計算hash的方式,屏蔽掉排序過程
前提是想一種在該題範圍內不會出現hash碰撞的方法
Code:
4ms 100%
RECORD數組是隨機數,也是會出現hash碰撞,但是測試用例中還撞不了
class Solution {
private final static int[] RECORD = {21,38,79,98,110,215,223,321,402,459,471,512,547,662,751,783,876,891,924,1005,1027,1131,1161,1170,1249,1287};
public int numSpecialEquivGroups(String[] A) {
HashSet<Integer> res = new HashSet<>();
for (String s : A) {
res.add(hash(s));
}
return res.size();
}
private static int hash(String str) {
int res = 0;
for (int i = 0; i < str.length(); i++) {
int idx = str.charAt(i++) - 97;
res += idx * 26 + RECORD[idx];
}
res*=10000;
for (int i = 1; i < str.length(); i++) {
int idx = str.charAt(i++) - 97;
res += idx * 31 + RECORD[idx];
}
return res;
}
}