题目描述:统计相似字符串对的数目Leecode
题目分析:
知识点回顾:
1.查询某个字符串是否存在 contains
用法:
str.contains(String str1)
作用:
查询str是否存在str1
举例:
String str = "abcd1234";
System.out.println(str+"判断 b 是否存在:"+str.contains("b"));
System.out.println(str+"判断 5 是否存在:"+str.contains("5"));
结果:
abcd1234判断 b 是否存在:true
abcd1234判断 5 是否存在:false
2.根据位置获取位置上某个字符。(截取一个字符)
char charAt(int index)
即 char charAt(值);
语法 :字符串名.charAt(值);
返回值为 char 类型。从字符串中取出指定位置的字符 。
3.根据字符获取该字符在字符串中的位置。
语法 :
字符串名.indexOf("字符");
字符串名.indexOf("字符",值);
查找一个指定的字符串是否存在,返回的是字符串的位置,如果不存在,则返回-1 。
错误答案:
class Solution {
public int similarPairs(String[] words) {
int count=0;
for(int i=0;i<words.length;i++){
for(int j=0;j<words.length-1-i;j++){
int flag=1;
for(int z=0;z<words[j].length();z++){
if(words[j+1].indexOf(words[j].charAt(z))!=-1){
}else{
flag=0;
}
}
if(flag==1){
count++;
}
}
}
return count;
}
}
错误原因:
???要用哈希???我还没学呢,哎,到底咋刷题啊,一刷一个我没学的。。。
我的错误就是因为我像冒泡排序一样,分别比较两个两个,但是用前面的字符来判断后边的那个字符串有没有这个字符时,会出现前面字符串的字符比较少,然而后边那个字符串该有的字符全有,但是比你多一些字符,这样你就可能没判断到了
思路和算法:
- 二进制数表示字符串:
- 每个字符串可以用一个26位的二进制数来表示,因为英语小写字母总共有26个(从'a'到'z')。
- 二进制数的每一位对应一个字母,如果该字母在字符串中存在,则对应位为1,否则为0。
- 例如,字符串 "abc" 可以表示为二进制数
000000000000000000000000000111
('a'在第0位,'b'在第1位,'c'在第2位,其余位为0)。
- 使用哈希表记录二进制数的次数:
- 遍历数组
words
,将每个字符串转换为对应的二进制数。 - 使用哈希表(或字典)来记录每个二进制数出现的次数。哈希表的键是二进制数(或其二进制字符串表示),值是该二进制数出现的次数。
- 遍历数组
- 计算相似字符串对的数目:
- 遍历哈希表,对于每个二进制数(或键),如果其对应的次数(或值)是
count
,则可以从这count
个字符串中任选两个字符串组成一对相似字符串。 - 相似字符串对的数量可以通过组合公式
count * (count - 1) / 2
计算得到。这是因为从count
个不同的项中选取两个项的组合数是C(count, 2) = count * (count - 1) / 2
。
- 遍历哈希表,对于每个二进制数(或键),如果其对应的次数(或值)是
- 遍历哈希表得到总相似字符串对数目:
- 将哈希表中每个二进制数对应的相似字符串对数目相加,即可得到整个数组
words
中的相似字符串对的总数。
- 将哈希表中每个二进制数对应的相似字符串对数目相加,即可得到整个数组
题解:
class Solution {
public int similarPairs(String[] words) {
Map<Integer, Integer> counts = new HashMap<Integer, Integer>();
for (String word : words) {
int mask = 0;
int length = word.length();
for (int i = 0; i < length; i++) {
char c = word.charAt(i);
mask |= 1 << (c - 'a');
}
counts.put(mask, counts.getOrDefault(mask, 0) + 1);
}
int pairs = 0;
Set<Map.Entry<Integer, Integer>> entries = counts.entrySet();
for (Map.Entry<Integer, Integer> entry : entries) {
int count = entry.getValue();
pairs += count * (count - 1) / 2;
}
return pairs;
}
}