LeetCode第214场周赛

本次LeetCode第214场周赛中,题目涉及数据结构和算法的巧妙应用。第一题相对简单,第二题为流程型问题。第三题通过二分法和贪心策略能有效降低时间复杂度,而第四题可采用树状数组或线段树模板。比赛体验到高手们的强大,并分享了零神关于第三题的二分法+贪心算法解题思路。
摘要由CSDN通过智能技术生成

收获满满的周赛:感受还是大佬们太强了……简单回顾一下第一题送分,第二题流程题,第三题视数据量应该使用二分法+贪心,第四题,套模板:树状数组或者线段树。

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;
    }
}

未完待续……

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值