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