- 对于每一个string s 对应的节点,我们遍历所有交换的可能,然后看交换后的string s'是否是图中的一个节点,是的话我们把s和s'连上一条边
- 对于输入数组的每一个string,我们check其和之前所有的string之间是否有边连接,每一次这样的check我们需要遍历整个字符串
假设数组长度为N,每个字符串长度为M。第一种方法的时间复杂度为O(N * M^2),第二种法法的时间复杂度为O(N^2 * M), 具体谁快取决于M和N的值。我们的解法采取第二种建图的方法。图建好后DFS或者并查集找connected component即可,我们采用DFS的解法,总的时间复杂度仍然是取决于建图的复杂度,代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
int numSimilarGroups(vector<string>& A) { | |
int n = A.size(); | |
vector<vector<int>> g(n); | |
for(int i = 1; i < n; ++i) | |
{ | |
for(int j = 0; j < i; ++j) | |
{ | |
if(isAdj(A[j], A[i])) | |
{ | |
g[i].push_back(j); | |
g[j].push_back(i); | |
} | |
} | |
} | |
int res = 0; | |
vector<bool> visited(n, false); | |
for(int i = 0; i < n; ++i) | |
{ | |
if(!visited[i]) | |
{ | |
dfs(g, visited, -1, i); | |
++res; | |
} | |
} | |
return res; | |
} | |
private: | |
bool isAdj(string u, string v) | |
{ | |
int len = u.size(), cnt = 0; | |
for(int i = 0; i < len; ++i) | |
{ | |
if(u[i] != v[i]) | |
if(++cnt > 2) | |
return false; | |
} | |
return true; | |
} | |
void dfs(vector<vector<int>>& g, vector<bool>& visited, int from, int to) | |
{ | |
if(visited[to])return; | |
visited[to] = true; | |
for(const auto& adj : g[to]) | |
{ | |
if(adj != from) | |
dfs(g, visited, to, adj); | |
} | |
} | |
}; |
No comments:
Post a Comment