这道题我在最初思考的时候陷入了误区,我最开始的思路是利用数组记录每个字母出现的次数,然后通过判断数组是否只有一个元素与其他元素不同且只相差1来判断是否能够删除一个字符使频率相同。然后在实际操作中,我发现情况实在太多了,根本考虑不全。
然后就一直在提交出错,加if判断,然后再报出另一种错,再加判断。这里举几个我最开始没有想到的情况,比如abcde,这个字符串每个字符都出现一次,并没有一个字符是比其他字符差一次,但实际上你无论删掉哪一个字符,他都可以保证频率相同,比如删掉a,得到bcde。
再比如字符串zzzzzz,随机删除一个也满足题意,但是aabb也是每个字符出现次数相同,又不满足题意,然后我就在我自己的这个思路中逐渐迷失,,,,
在我经历了八次提交错误后,我删掉了所有的代码,改变了我的思路,也就是下面的思路。
既然我无法判断他能否满足删除一个后构成平衡字符串,那我就先删除一个字符,然后再去判断他是否是一个平衡字符串,这就是我下面这个思路的核心。
然后来介绍我成功通过的思路:
1.这个解法的关键在于如何判断这个字符串是平衡字符串。
首先题目说明字符串由小写字母构成,我们想到使用长为26 的数组来记录每个字母出现的次数,那么我们的数组长为26,那么没有出现过的字母下标对应的数组元素为0,所以如果他是一个平衡字符串,那我们这个数组只可能是有两种元素,那就是0还有公共的出现次数。
所以我们利用hashset,向其中加入0和数组中一个不为0的元素。
如果在数组中出现了其他的元素,那他一定不是平衡字符串。否则就是平衡字符串。
2.完成我们判断字符串是否字符频率相等的方法后,那就是开始遍历一个字符串在删除一个字符后是否可以构成平衡字符串,只要在删除任意一个字符能构成平衡字符串,就满足要求。
然后我们这道题就完成了,这道题开始我以为很简单,但是在进入了错误的思路后,却多次出错,所以在一条路走不通时,不能不舍得舍弃敲好的代码,不然会越陷越深的,这就是我从这道题中吸取的经验。
希望可以帮到大家,如果的思路有什么不对的地方,或者大家有什么好的建议,希望大家可以畅所欲言,希望可以通过这种方式,大家共同进步。
以下是我的代码:
class Solution {
public boolean equalFrequency(String word) {
/*
遍历字符串的每个字符,分别判断删除每个字符时能否构成平衡字符串。
*/
StringBuffer sb;
for(int i=0;i<word.length();i++){
sb=new StringBuffer(word);
sb.deleteCharAt(i);
boolean result=judge(sb.toString());
if(result==true)return true;
}
return false;
}
//judge()方法用于判断一个字符串是否是平衡字符串
public boolean judge(String word){
int[] count=new int[26];//创建一个数组用来记录字符串中每个字母出现的次数
for(int i=0;i<word.length();i++){
count[word.charAt(i)-'a']++;
}
var site=new HashSet<Integer>();//创建hashset用来记录所传入字符串的出现次数的种类
/*
若是一个平衡字符串,那么该字符串中每个字符出现次数都相等,而且字符串中可能会有未出现的字母,所以哈希集合中只会存在两个元素,那就是 0 和 每个字母出现的次数。
*/
site.add(0);
for(int j=0;j<26;j++){
if(count[j]!=0){
site.add(count[j]);
break;
}
}
//如果hashset中出现了另外的元素,那必定不是平衡字符串。
for(int m=0;m<26;m++){
if(!site.contains(count[m])){
return false;
}
}
return true;
}
}