记录两道笔试
1. 给定一个字符串,每个字符只能选一次,可以拼成多少个“ccbft”?(不限大小写)
思路:遍历字符串,用数组模拟哈希表统计"ccbft"中的字符出现的次数(统一把大写看做小写),遍历数组,最小值就是能拼成的次数。(只过了87%)
public int countSeq (String mystr) {
char[] s = mystr.toCharArray();
char[] target = "ccbft".toCharArray();
int[] map = new int[26];
for(char ch: s) {
if(ch == 'C' || ch == 'c') {
map['c'-'a']++;
}
if(ch == 'B' || ch == 'b') {
map['b'-'a']++;
}
if(ch == 'F' || ch == 'f') {
map['f'-'a']++;
}
if(ch == 'T' || ch == 't') {
map['t'-'a']++;
}
}
//因为c需要出现两次
map['c'-'a'] /= 2;
//遍历map找到最小的val就是能拼的最多次数
int min = Integer.MAX_VALUE;
for(int n : map) {
if(n > 0) {
min = Math.min(min, n);
}
}
return min < Integer.MAX_VALUE ? min : 0;
}
2. 给定字符串,可以删除一些字符,至少需要删除多少个字符可以使得各个字符出现的次数各不相同?
用哈希表统计每个字符出现的次数,把values()存入int[]后排序,从后往前遍历,统计当前元素和上限的差值(上限是前一个字符-1)
public int Delete_character (String s) {
// write code here
char[] str = s.toCharArray();
Map<Character, Integer> map = new HashMap<>();
for(char ch: str) {
map.put(ch, map.getOrDefault(ch, 0)+1);
}
int[] a = new int[map.size()];
int k = 0;
for(int n: map.values()) {
a[k++] = n;
}
Arrays.sort(a);
int ans = 0;
//当前元素上限
int max = a[a.length-1];
for(int i = a.length-1; i >= 0; i--) {
//当超过上限时在统计了差额后,需要更新当前元素
if(a[i] > max) {
ans += (a[i]-max);
a[i] = max;
}
//上限是前一个元素(删除后的)-1
max = Math.max(0, a[i]-1);
}
return ans;
}

