2023-2-20刷题情况

将整数减少到零需要的最少操作数

题目描述

给你一个正整数 n ,你可以执行下述操作 任意 次:

n 加上或减去 2 的某个 幂
返回使 n 等于 0 需要执行的 最少 操作数。

如果 x == 2i 且其中 i >= 0 ,则数字 x 是 2 的幂。

样例

样例输入

n = 39
n = 54

样例输出

3
解释:我们可以执行下述操作:
n 加上 20 = 1 ,得到 n = 40 。
n 减去 23 = 8 ,得到 n = 32 。
n 减去 25 = 32 ,得到 n = 0 。
可以证明使 n 等于 0 需要执行的最少操作数是 3 。

3
解释:我们可以执行下述操作:
n 加上 21 = 2 ,得到 n = 56 。
n 加上 23 = 8 ,得到 n = 64 。
n 减去 26 = 64 ,得到 n = 0 。
使 n 等于 0 需要执行的最少操作数是 3 。

提示

  • 1 < = n < = 1 0 5 1 <= n <= 10^5 1<=n<=105

思路

二的某个幂,那不就是说明了,这个题需要用二进制来做,然后求当前是+或者-能够使得当前二进制数中的1数量减到最少,因为1111这种类型的存在,+1会比-1使得当前二进制数中的1数量减少。还有这二个测试用例很好,通过测试用例就知道当+1与-1的结果都一致,需要选择+1.

代码实现

class Solution {
    public int minOperations(int n) {
        int ans = 0;
        while(n > 0){
            ans++;
            int s1 = lowbit(n + (n&(-n)));
            int s2 = lowbit(n - (n&(-n)));
            if(s2 == 0) break;  
            if(s1 <= s2) n += (n&(-n));
            else n -= (n&(-n));
        }
        return ans;
    }
    
    // 求出当前数的二进制形式中有多少个1.
    private int lowbit(int x){
        int index = 0;
        while(x > 0){
            x -= x&(-x);
            index++;
        }
        return index;
    }
}

最大平均通过率

题目描述

一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。给你一个二维数组 classes ,其中 classes[i] = [passi, totali] ,表示你提前知道了第 i 个班级总共有 totali 个学生,其中只有 passi 个学生可以通过考试。

给你一个整数 extraStudents ,表示额外有 extraStudents 个聪明的学生,他们 一定 能通过任何班级的期末考。你需要给这 extraStudents 个学生每人都安排一个班级,使得 所有 班级的 平均 通过率 最大 。

一个班级的 通过率 等于这个班级通过考试的学生人数除以这个班级的总人数。平均通过率 是所有班级的通过率之和除以班级数目。

请你返回在安排这 extraStudents 个学生去对应班级后的 最大 平均通过率。与标准答案误差范围在 10-5 以内的结果都会视为正确结果。

样例

样例输入

classes = [[1,2],[3,5],[2,2]], extraStudents = 2
classes = [[2,4],[3,9],[4,5],[2,10]], extraStudents = 4

样例输出

0.78333
解释:你可以将额外的两个学生都安排到第一个班级,平均通过率为 (3/4 + 3/5 + 2/2) / 3 = 0.78333 。

0.53485

提示

  • 1 < = c l a s s e s . l e n g t h < = 1 0 5 1 <= classes.length <= 10^5 1<=classes.length<=105
  • c l a s s e s [ i ] . l e n g t h = = 2 classes[i].length == 2 classes[i].length==2
  • 1 < = p a s s i < = t o t a l i < = 1 0 5 1 <= passi <= totali <= 10^5 1<=passi<=totali<=105
  • 1 < = e x t r a S t u d e n t s < = 1 0 5 1 <= extraStudents <= 10^5 1<=extraStudents<=105

思路

贪心思想,需要把班级通过一种特殊的方式排序,这个特殊的排序归责就是加入一个通过的学生对班级的平均通过率提升最大来排序。因为需要有多次取按照指定排序规则中的最大值,所以优先队列最为合适。

代码实现

class Solution {
    public double maxAverageRatio(int[][] classes, int extraStudents) {
        int len = classes.length;
        PriorityQueue<double[]> queue = new PriorityQueue<>((a, b) -> {
           double x = (a[0] + 1) / (a[1] + 1) - a[0] / a[1];
           double y = (b[0] + 1) / (b[1] + 1) - b[0] / b[1];
           if(x > y) return -1;
           if(y < x) return 1;
           return 0;
        });

        for(int[] c : classes) queue.offer(new double[]{c[0], c[1]});
        
        while(extraStudents-- > 0){
            double[] cur = queue.poll();
            cur[0] += 1.0;
            cur[1] += 1.0;
            queue.offer(cur);
        }
        double ans = 0;
        while(!queue.isEmpty()){
            double[] c = queue.poll();
            ans += (c[0] / c[1]);
        }
        return ans / len;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值