题目链接:3020. 子集中元素的最大数量(中等)
算法原理:
解法:哈希表
56ms击败84.73%
时间复杂度O(N)
整体思路:将所有数扔进哈希表,然后逐一遍历,看这个数出现了几次,如果出现1次,就让 mx 和 1 更新最大值,否则就继续探寻
这里的探寻的意思:如果这个数是 2,那么就看 4是否存在:
①如果不存在:退出探寻
②如果存在:更新 mx
如果 4 只出现 1 次,不再探寻了,因为无法保证两边对称
如果 4 出现≥ 2 次,继续探寻
这里更新的时候,注意这里的幂数是2的 k 次幂,因此取值的时候,需要套两层 Math.pow()
这个数就可以表示为:Math.pow(key,Math.pow(2,k)),我们后续更新 mx 的时候就可以通过 k 来更新
拿 2 , 4 , 16, 4 , 2 为例,表示为 2¹ , 2² , 2⁴ , 2² , 2¹ 这里 k 最大为 3,那么长度就是 2 × 3 -1 = 5,因此更新的长度表示为 2 × k + 1
特殊情况处理:当 key 为 1 时,1¹ = 1、1² = 1、1⁴ = 1......
因此这个时候只需要统计 1 的个数 n 即可:
n 为奇数,mx = max(mx,n)
n 为偶数,mx = max(mx,n-1)
细节:使用 Math.pow() 时,要注意精度转换,将 double 强制转换成 int
Java代码:
java
class Solution {
//3020. 子集中元素的最大数量
public int maximumLength(int[] nums) {
if(nums.length==0) return 0;
Map<Integer,Integer> hash=new HashMap<>();
for(int x:nums) hash.merge(x,1,Integer::sum);
int mx=1;
for(Map.Entry<Integer,Integer> entry:hash.entrySet()){
int key=entry.getKey();
int val=entry.getValue();
//特殊处理:1
if(key==1){
int n=hash.get(1);
if(n%2==1) mx=Math.max(mx,n);
else mx=Math.max(mx,n-1);
continue;
}
if(val==1){
mx=Math.max(mx,1);
continue;
}
int k=1;
while(hash.containsKey((int)Math.pow(key,Math.pow(2,k)))){
mx=Math.max(mx,2*k+1);
if(hash.get((int)Math.pow(key,Math.pow(2,k)))==1) break;
k++;
}
}
return mx;
}
}