#839 Similar String Groups

Description

Two strings X and Y are similar if we can swap two letters (in different positions) of X, so that it equals Y. Also two strings X and Y are similar if they are equal.

For example, “tars” and “rats” are similar (swapping at positions 0 and 2), and “rats” and “arts” are similar, but “star” is not similar to “tars”, “rats”, or “arts”.

Together, these form two connected groups by similarity: {“tars”, “rats”, “arts”} and {“star”}. Notice that “tars” and “arts” are in the same group even though they are not similar. Formally, each group is such that a word is in the group if and only if it is similar to at least one other word in the group.

We are given a list strs of strings where every string in strs is an anagram of every other string in strs. How many groups are there?

Examples

Example 1:

Input: strs = [“tars”,“rats”,“arts”,“star”]
Output: 2

Example 2:

Input: strs = [“omv”,“ovm”]
Output: 1

Constraints:

1 <= strs.length <= 300
1 <= strs[i].length <= 300
strs[i] consists of lowercase letters only.
All words in strs have the same length and are anagrams of each other.

思路

我用的是judgeSimiliar+bfs
要注意的是我一开始的judgeSimiliar判断了两个单词是否为“swap”,后面发现不用,constraints里面的anagram我不太理解意思,但实际应用下来发现只要统计两个单词的“不同字符个数”<=2即可

另:有看到用并查集的,下次再关心一下

代码

class Solution {
	// first way(judge "swap")
	public boolean isSimiliar2(String a, String b) {
        if (a.equals(b))
            return true;
        
        int i = 0;
        for (i = 0; i < a.length(); i++) {
            if (a.charAt(i) != b.charAt(i))
                break;
        }
        char tmpA = a.charAt(i);
        char tmpB = b.charAt(i);
        
        for(i = i + 1; i < a.length(); i++) {
            if (a.charAt(i) != b.charAt(i))
                break;
        }
        if (i == a.length())
            return false;
        
        if (tmpA != b.charAt(i) || tmpB != a.charAt(i))
            return false;
        
        if (i == a.length() - 1)
            return true;
        
        return a.substring(i + 1).equals(b.substring(i + 1));   
    }
	
	// second way(judge counts)
    public boolean isSimiliar(String a, String b) {
        int count = 0;
        for (int i = 0; i < a.length(); i++) {
            if (a.charAt(i) != b.charAt(i))
                count += 1;
            if (count > 2)
                return false;
        }
        
        return true;
    }
    
    public int numSimilarGroups(String[] strs) {
        int[][] adj = new int[strs.length][strs.length];
        
        for(int i = 0; i < strs.length; i++){
            adj[i][i] = 1;
            for(int j = i + 1; j < strs.length; j++){
                int isAdj = isSimiliar(strs[i], strs[j])? 1: 0;
                adj[i][j] = isAdj;
                adj[j][i] = isAdj;
            }
        }
        
        int groupCount = 0;
        int[] visited = new int[strs.length];
        
        for (int i = 0; i < strs.length; i++) {
            if (visited[i] == 1)
                continue;
            
            List<Integer> neighbors = new ArrayList<>();
            neighbors.add(i);
            while(neighbors.size() > 0) {
                int curr = neighbors.get(0);
                for (int j = 0; j < strs.length; j++) {
                    if (adj[curr][j] == 1 && visited[j] == 0){
                        visited[j] = 1;
                        neighbors.add(j);
                    }
                }
                neighbors.remove(0);
            }
            groupCount += 1;
        }
        
        return groupCount;   
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值