2021-03-14 第 232 场周赛

2021-03-14 第 232 场周赛

1790. 仅执行一次字符串交换能否使两个字符串相等

思路:签到题,把不相等的字符分别记录,判断是否反转后一致即可。

class Solution {
    public boolean areAlmostEqual(String s1, String s2) {
        int cnt = 0;
        StringBuffer s3 = new StringBuffer();
        StringBuffer s4 = new StringBuffer();
        for(int i = 0;i < s1.length();i++) {
            if(s1.charAt(i) != s2.charAt(i)) {
                s3.append(s1.charAt(i));
                s4.append(s2.charAt(i));
            }
        }
        return s3.length() == 0 || 
                (s3.length() == 2 && s3.toString().equals(s4.reverse().toString()));
    }
}

1791. 找出星型图的中心节点

在这里插入图片描述

思路:找出出现了n次的数即可

class Solution {
    int mx = (int) (1e5 + 10);
    int[] cnt = new int[mx];
    public int findCenter(int[][] edges) {
        int n = edges.length, res = 0;
        for(int[] e:edges) {
            cnt[e[0]]++;
            cnt[e[1]]++;
        }
        for(int i = 1;i < mx;i++) {
            if(cnt[i] == n) {
                res = i;
                break;
            }
        }
        return res;
    }
}

1792. 最大平均通过率

在这里插入图片描述

思路:贪心的思想,假设每个班级的通过率为 r i r_i ri,那么平均通过率为 ∑ i = 1 n r i n \frac{\sum_{i=1}^n{r_i}}{n} ni=1nri。而又可以知道, x + 1 y + 1 ≥ x y \frac{x+1}{y+1} \geq \frac{x}{y} y+1x+1yx,说明每个加进来额外的学生都会使得原先班级的通过率增加或者不变。

设增加一个学生后该班级通过率的增量为 d i f f = x + 1 y + 1 − x y diff = \frac{x+1}{y+1} - \frac{x}{y} diff=y+1x+1yx,则我们要选择增量最大的班级来分配额外的学生。这里可以使用最大堆来做,堆顶的班级就是增量最大的班级。

class Solution {
    public double maxAverageRatio(int[][] classes, int extraStudents) {
        int n = classes.length;
        double rate = 0;
        // 维护增量最大的最大堆
        PriorityQueue<double[]> q = new PriorityQueue<>(new Comparator<double[]>() {
            @Override
            public int compare(double[] o1, double[] o2) {
                double diff1 = (o1[0]+1)/(o1[1]+1) - (o1[0]/o1[1]);
                double diff2 = (o2[0]+1)/(o2[1]+1) - (o2[0]/o2[1]);
                if(diff2 > diff1)
                    return 1;
                return -1;
            }
        });
        for(int[] c:classes) {
            q.offer(new double[]{c[0], c[1]});
        }
        // 挑选出增量最大的班级
        while(extraStudents-- > 0) {
            double[] c = q.poll();
            c[0] += 1;
            c[1] += 1;
            q.offer(c);
        }
        while(q.size() > 0) {
            double[] c = q.poll();
            rate += (c[0] / c[1]);
        }
        return rate/n;
    }
}

1793. 好子数组的最大分数

在这里插入图片描述

思路:这道压轴题还是比较简单的。只需要遍历数组,将每个值作为最小值,找出以该值为最小值的左右边界分别在什么位置,然后比较得出答案即可。

class Solution {
    public int maximumScore(int[] nums, int k) {
        int n = nums.length, res = 0;
        int[] l = new int[n], r = new int[n];
        l[0] = -1;  r[n-1] = n;

        for(int i = 1;i < n;i++) {
            int j = i-1;
            while(j != -1 && nums[j] >= nums[i]) {
                j = l[j];
            }
            l[i] = j;
        }
        for(int i = n-2;i >= 0;i--) {
            int j = i+1;
            while(j != n && nums[j] >= nums[i]) {
                j = r[j];
            }
            r[i] = j;
        }

        for(int i = 0; i < n;i++) {
            int left = l[i], right = r[i];
            if(left+1 <= k && right-1 >= k) {
                res = Math.max(res, (right-left-1)*nums[i]);
            }
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值