zoukankan      html  css  js  c++  java
  • 竞赛202

    1552. 两球之间的磁力

    在代号为 C-137 的地球上,Rick 发现如果他将两个球放在他新发明的篮子里,它们之间会形成特殊形式的磁力。Rick 有 n 个空的篮子,第 i 个篮子的位置在 position[i] ,Morty 想把 m 个球放到这些篮子里,使得任意两球间 最小磁力 最大。

    已知两个球如果分别位于 x 和 y ,那么它们之间的磁力为 |x - y| 。

    给你一个整数数组 position 和一个整数 m ,请你返回最大化的最小磁力。

    示例 1:

     

    输入:position = [1,2,3,4,7], m = 3
    输出:3
    解释:将 3 个球分别放入位于 1,4 和 7 的三个篮子,两球间的磁力分别为 [3, 3, 6]。最小磁力为 3 。我们没办法让最小磁力大于 3 。
    示例 2:

    输入:position = [5,4,3,2,1,1000000000], m = 2
    输出:999999999
    解释:我们使用位于 1 和 1000000000 的篮子时最小磁力最大。
     

    提示:

    n == position.length
    2 <= n <= 10^5
    1 <= position[i] <= 10^9
    所有 position 中的整数 互不相同 。
    2 <= m <= position.length

    /**
     * @param {number[]} position
     * @param {number} m
     * @return {number}
     */
    var maxDistance = function(position, m) {
        position.sort((a, b)=>a-b);
        let len = position.length;
        // 2个球任意距离的最小值
        let r = Math.floor((position[len-1]-position[0])/(m-1));
        let l = 1;
        const check = (mid)=>{
            let count =1; // 0点位置放一个球
            let j = 0;
            for(let i=1; i<len; i++){
                if(position[i]-position[j] >=mid){
                    count++;
                    j=i;
                    if(count>=m) return true
                }
            }
            return false
        }
        let res;
        while(l<=r){
            let mid = Math.floor((l+r)/2);
            // 是否能达到 mid 距离
            if(check(mid)){
                res = mid;
                l = mid+1;
            } else {
                r = mid-1;
            }
        }
        return res;
    };

    思考:这个当时,我也想到二分法,并且感觉二分可以解决的,把索引二分(当时想到了),索引对应的值二分(当时想到了),但是就不知道怎么处理了,当时还一直有个想法就是遍历点注定会超时,这个想法导致自己不想去循环这个数组。

    位置排序后根据初始和结束 ,以及球的个数是可以知道最大化距离的,但所给的点不一定满足要求,(当时想到了)

    步骤一:把最大距离“二分法”,看所给的点满足要求吗?l=1, r = max,mid = Math.floor((l+r)/2), 遍历所给的点看是否能达到mid。

    步骤二:l = mid+1, r=  max 或 l= 1, r = mid-1, ,mid = Math.floor((l+r)/2), 遍历所给的点看是否能达到mid。

    重复(步骤二)这个过程。

     关于“二分法” 为什么会出现 mid+1 或 mid-1

     l=97 => 98, 如果此时 98 没有 +1, 那么 l=98, =>min =98 => 又赋值给l =98 =>死循环,所以 必须有 l = mid+1 => l= 98+1

    最终的判断条件 l<=r, 最后满足的条件是左边 = 右边。

    1553. 吃掉 N 个橘子的最少天数

    厨房里总共有 n 个橘子,你决定每一天选择如下方式之一吃这些橘子:

    吃掉一个橘子。
    如果剩余橘子数 n 能被 2 整除,那么你可以吃掉 n/2 个橘子。
    如果剩余橘子数 n 能被 3 整除,那么你可以吃掉 2*(n/3) 个橘子。
    每天你只能从以上 3 种方案中选择一种方案。

    请你返回吃掉所有 n 个橘子的最少天数。

    示例 1:

    输入:n = 10
    输出:4
    解释:你总共有 10 个橘子。
    第 1 天:吃 1 个橘子,剩余橘子数 10 - 1 = 9。
    第 2 天:吃 6 个橘子,剩余橘子数 9 - 2*(9/3) = 9 - 6 = 3。(9 可以被 3 整除)
    第 3 天:吃 2 个橘子,剩余橘子数 3 - 2*(3/3) = 3 - 2 = 1。
    第 4 天:吃掉最后 1 个橘子,剩余橘子数 1 - 1 = 0。
    你需要至少 4 天吃掉 10 个橘子。
    示例 2:

    输入:n = 6
    输出:3
    解释:你总共有 6 个橘子。
    第 1 天:吃 3 个橘子,剩余橘子数 6 - 6/2 = 6 - 3 = 3。(6 可以被 2 整除)
    第 2 天:吃 2 个橘子,剩余橘子数 3 - 2*(3/3) = 3 - 2 = 1。(3 可以被 3 整除)
    第 3 天:吃掉剩余 1 个橘子,剩余橘子数 1 - 1 = 0。
    你至少需要 3 天吃掉 6 个橘子。
    示例 3:

    输入:n = 1
    输出:1
    示例 4:

    输入:n = 56
    输出:6
     

    提示:

    1 <= n <= 2*10^9

    // 这个是超时的
    /**
     * @param {number} n
     * @return {number}
     */
    var minDays = function(n) {
        // 吃 n 个橘子 最少天数是 d[n]
        let dp = new Array(n+1).fill(0);
        dp[1] = 1;
        dp[2] = 2; 
        for(let i=3; i<=n; i++){
            let m1 = Infinity, m2 = Infinity, m3 = Infinity;
            // 必须加 ()
            if(!(i%2)){
                m1 = dp[i/2]+1
            }
            if(!(i%3)){
                m2 = dp[i/3]+1
            }
            m3 = dp[i-1]+1
            dp[i] = Math.min(m1, m2, m3)
        }
        return dp[n]
    };

    思考: 记得当时,想着用dp,然后还递归 getCount(n-1), 根据往常经验还循环了一下,n是橘子,最初始的条件是, n=1时,返回1,不知道改怎么去dp这道题。

    还是没梳理清楚关系,dp[i] 代码 i 个橘子最少吃 dp[i] 天

     
    var minDays = function(n) {
        let d = [];
        const dfs = (n, d)=>{
            if(n===1) return 1;
            if(n===2) return 2;
            if(d[n]) return d[n];
            let ans = Infinity;
            ans = Math.min(ans, n % 2 + dfs(Math.floor(n/2),d)+1)
            ans = Math.min(ans, n % 3 + dfs(Math.floor(n/3),d)+1)
            return d[n] = ans
        }
        return dfs(n, d)
    }
    来源:力扣(LeetCode)

    链接:https://leetcode-cn.com/problems/magnetic-force-between-two-balls
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 相关阅读:
    014 要区分好slice,splice和split,方法如下
    108 shutil模块(了解)
    107 pathlib模块(了解)
    106 collections模块
    105 typing模块
    104 re模块
    103_01 matplotlib模块
    102 pandas模块
    101 numpy模块
    SQLserver找出执行慢的SQL语句
  • 原文地址:https://www.cnblogs.com/zhangzs000/p/13516436.html
Copyright © 2011-2022 走看看