收获满满的周赛:感受还是大佬们太强了……简单回顾一下第一题送分,第二题流程题,第三题视数据量应该使用二分法+贪心,第四题,套模板:树状数组或者线段树。
1646. 获取生成数组中的最大值
class Solution {
public int getMaximumGenerated(int n) {
if(n==0){
return 0;
}
if(n==1){
return 1;
}
int []res=new int [n+1];
res[0]=0;
res[1]=1;
int max=Integer.MIN_VALUE;
for(int i=2;i<=n;i++){
if(i%2==0){
res[i]=res[i/2];
}else{
res[i]=res[i/2]+res[i/2+1];
}
max=Math.max(res[i],max);
}
return max;
}
}
1647. 字符频次唯一的最小删除次数
class Solution {
public int minDeletions(String s) {
Map<Character,Integer>map=new HashMap<>();//map用来统计所有的字符串以及个数
char[]temp=s.toCharArray();
for(char cc:temp){
if(!map.containsKey(cc)){
map.put(cc,1);
}else{
map.put(cc,map.get(cc)+1);
}
}
int len=map.size();
int []res=new int [len];
Set<Character>set=map.keySet();
int i=0;
for(char ss:set){
res[i++]=map.get(ss);
}
int sum=0;
Arrays.sort(res);//将字符串出现的次数进行排序
if(res[len-1]==1){//从最后一个位置开始,排除都出现一次的情况
return len-1;
}
int index=len-2;
while(index>=0){
while(res[index]>=res[index+1]){
sum++;
res[index]--;
if(res[index]==0){
break;
}
}
index--;
}
return sum;
}
}
1648. 销售价值减少的颜色球
比赛中我想到用大顶堆,时间复杂度NlogN
,明显超时,也看到有人优化这个算法,但是还是没有下面用二分法+贪心算法好……
class Solution {
public int maxProfit(int[] inventory, int orders) {
//大顶堆:
int k=1;
PriorityQueue<Integer> pq
= new PriorityQueue<Integer>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1; //小顶堆o1-o2,大顶堆o2-o1;
}
});
for(int tmp:inventory){
pq.offer(tmp);
}
int res=0;
for(int i=0;i<orders;i++){
int tt=pq.peek();
res+=pq.poll();
pq.offer(tt-1);
}
//return res;
return (int)(res%(Math.pow(10,9)+7));
}
}
根据零神的思路改写成java
版本的:先找到一个指标,,然后使用等差数列,详解题解。
public class Solution {
int mod = 1000000007;
public int maxProfit(int[] inventory, int orders) {
// 二分法求T
long left = 0;
Arrays.sort(inventory);
long right = inventory[inventory.length - 1];
long t = (left + right) / 2;
while (left <= right) {
t = (left + right) / 2;
if (calCount(inventory, t) <= orders) {
right = t - 1;
} else {
left = t + 1;
}
}
// 最终根据上述二分算法可以解得这个标准temp
long temp=left;
long result = 0;
long rest = orders - calCount(inventory, temp);
for (long i : inventory) {
if (i >= temp) {
if (rest > 0) {
result += (long) (i + temp) * (i - temp + 1) / 2;
rest--;
} else {
result += (long) (i + temp + 1) * (i - temp) / 2;
}
}
}
return (int) (result % mod);
}
//计算这个指标:可以数组中所有的数都减去这个数,得到的个数再求和
private long calCount(int[] inventory, long limit) {
long count = 0;
for (int i : inventory) {
if (i >= limit) {
count += i - limit;
}
}
return count;
}
}
未完待续……