要求
给你一个正整数数组 nums,请你帮忙从该数组中找出能满足下面要求的 最长 前缀,并返回该前缀的长度:
从前缀中 恰好删除一个 元素后,剩下每个数字的出现次数都相同。
如果删除这个元素后没有剩余元素存在,仍可认为每个数字都具有相同的出现次数(也就是 0 次)。来源:力扣(LeetCode)
解题思路
1, 既然是前缀,就应该从零开始(一开始考虑复杂了,以为是从字符串中截取符合条件的字符串呢)
2, 要符合条件,字符的频率只能是1个或两个
1)频率为1时,要么字符不重复,要么字符都一样
2)频率为2时,存在一个频率为1 或者 俩个的频率差为1
代码
class Solution {
public int maxEqualFreq(int[] nums) {
int maxIndex = 0;
int numCount = nums.length;
if(numCount > 100000){
return maxIndex;
}
// 存储每个字符的出现频率
HashMap<Integer,Integer> map = new HashMap<>();
// 存储每个频率出现的次数
HashMap<Integer,Integer> pinMap = new HashMap<>();
for(int i=0;i<numCount;i++){
Integer a = nums[i];
if(a > 100000){
return 0;
}
Integer feq = map.getOrDefault(a,0);
if(feq > 0 ) {
if(pinMap.getOrDefault(feq,0)>1){
pinMap.put(feq,pinMap.get(feq)-1);
} else {
pinMap.remove(map.get(a));
}
}
Integer feqCount = pinMap.getOrDefault(feq+1,0)+1;
pinMap.put(feq+1,feqCount);
Integer[] arr = pinMap.keySet().stream().distinct().toArray(Integer[]::new); map.put(a,feq+1);
boolean updateFlag = updatMax(map,pinMap,arr);
if(updateFlag){
maxIndex = i;
}
System.out.println(maxIndex);
}
return maxIndex+1;
}
public boolean updatMax(HashMap<Integer,Integer> map,HashMap<Integer,Integer> pinMap,Integer[] arr){
int count =arr.length;
if(count>2){
return false;
}
// 1个频率
if(count == 1 ){
// 每个字符就出现1次
if(arr[0] == 1){
return true;
}
// 相同的字符
if(map.size() == 1){
return true;
}
}
// 如果出现俩个频次,则频次为1或俩个频次差为1
if(count == 2){
Integer a = arr[0],b=arr[1];
if(a == 1 && pinMap.get(a) ==1){
return true;
}
if(b == 1 && pinMap.get(b) ==1){
return true;
}
if(a - b ==1 && pinMap.get(a) == 1){
return true;
}
if(b - a ==1 && pinMap.get(b) == 1){
return true;
}
}
return false;
}
}
待优化
目前只是最低满足时间要求,频率获取这块用数组应该更好些