1、题目描述
2、题目分析
常规思路:
记录出现频率的,遍历获取次数,【数组】或者【哈希表】。
2-1、下面是【哈希表】实现,比较暴力,复杂度有些偏高!
1、哈希表记录,遍历secret,此时下标设置为i, 位置一致的且值也一致的,则属于题目中完全匹配,即公牛A的数量,countA++; 并记录对应的下标值,放入哈希表 indexS中;
2、其余未匹配的存入哈希表中,设置哈希表名称 need 中;
3、再遍历guess,如果是indexS中的下标,说明之前已经匹配上属于公牛A的,则跳过;
4、不在indexS下标中的,查询是否在哈希表need中,如果存在,获取在need中的频次数,同时新建哈希表存在guess中的频次数,超过need中的频次数,说明是【多重复的无用字母】,不算countB数量,未超过need中的频次数,则进行countB++.
代码实现:
class Solution {
public String getHint(String secret, String guess) {
Map<Character,Integer> need = new HashMap<Character,Integer>();
Map<Character,Integer> guessMark = new HashMap<Character,Integer>();
Set<Integer> indexS = new HashSet<Integer>();
int countA = 0;
int countB = 0;
for(int i = 0; i < secret.length(); i++){
char c = secret.charAt(i);
char g = guess.charAt(i);
// 完全一致,公牛数量增加,即countA++;
if(c == g){
countA++;
indexS.add(i);
continue;
}
//未匹配上的放入map中,map进行记录原字符串【未匹配】数据
if(need.containsKey(c)){
need.put(c, need.get(c)+1);
}else{
need.put(c,1);
}
}
for(int j = 0; j< guess.length(); j++){
//已经匹配上的下标就跳过
if(indexS.contains(j))
continue;
char d = guess.charAt(j);
if(need.containsKey(d)){
int needCount = need.get(d);
int needGuess = 0;
if(guessMark.containsKey(d)){
needGuess = guessMark.get(d);
}
if(needGuess < needCount){
countB++;
}
guessMark.put(d, needGuess+1);
}
}
return Integer.toString(countA)+"A"+Integer.toString(countB)+"B";
}
}
复杂度分析
时间复杂度:O(N),其中 N 是字符串 secret 的长度,遍历了secret 和 guess,其实是O(2N) 映射为O(N)。
空间复杂度:O(N)。对应哈希表的空间。
用【哈希表】实现,确实相对来说,代码相对复杂,且复杂度较高。执行后也比较耗时:
2-2、下面是用【数组】实现
class Solution {
public String getHint(String secret, String guess) {
int countA = 0;
int[] cnts = new int[10];
int[] cntg = new int[10];
for(int i = 0; i < secret.length(); i++ ){
if(secret.charAt(i) == guess.charAt(i)){
countA++;
}else{
//不匹配的写入数组中记录,由于是char型,转化成数字需要-‘0’获取差值
cnts[secret.charAt(i)-'0']++;
cntg[guess.charAt(i)-'0']++;
}
}
// 以下是难点,两个字符串未完全匹配上的‘字符’
// 两个数组【具体每个数字出现次数最小值】,代表相同数字不同位置
int countB = 0;
for(int i = 0; i< 10; i++){
countB += Math.min(cnts[i],cntg[i]);
}
return Integer.toString(countA)+"A"+Integer.toString(countB)+"B";
}
}
复杂度分析
时间复杂度:O(N),其中 NN 是字符串 secret 的长度。
空间复杂度:O(C)。需要常数个空间统计字符出现次数,由于我们统计的是数字字符,因此 C=10。
备注:此时的效率就提高了很多,编译截图如下