返回介绍

solution / 2700-2799 / 2702.Minimum Operations to Make Numbers Non-positive / README_EN

发布于 2024-06-17 01:03:01 字数 5654 浏览 0 评论 0 收藏 0

2702. Minimum Operations to Make Numbers Non-positive

中文文档

Description

You are given a 0-indexed integer array nums and two integers x and y. In one operation, you must choose an index i such that 0 <= i < nums.length and perform the following:

  • Decrement nums[i] by x.
  • Decrement values by y at all indices except the ith one.

Return _the minimum number of operations to make all the integers in _nums _less than or equal to zero._

 

Example 1:

Input: nums = [3,4,1,7,6], x = 4, y = 2
Output: 3
Explanation: You will need three operations. One of the optimal sequence of operations is:
Operation 1: Choose i = 3. Then, nums = [1,2,-1,3,4]. 
Operation 2: Choose i = 3. Then, nums = [-1,0,-3,-1,2].
Operation 3: Choose i = 4. Then, nums = [-3,-2,-5,-3,-2].
Now, all the numbers in nums are non-positive. Therefore, we return 3.

Example 2:

Input: nums = [1,2,1], x = 2, y = 1
Output: 1
Explanation: We can perform the operation once on i = 1. Then, nums becomes [0,0,0]. All the positive numbers are removed, and therefore, we return 1.

 

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109
  • 1 <= y < x <= 109

Solutions

Solution 1: Binary Search

We notice that if an operation count $t$ can make all numbers less than or equal to $0$, then for any $t' > t$, the operation count $t'$ can also make all numbers less than or equal to $0$. Therefore, we can use binary search to find the minimum operation count.

We define the left boundary of the binary search as $l=0$, and the right boundary as $r=\max(nums)$. Each time we perform a binary search, we find the middle value $mid=\lfloor\frac{l+r}{2}\rfloor$, and then determine whether there exists an operation method that does not exceed $mid$ and makes all numbers less than or equal to $0$. If it exists, we update the right boundary $r = mid$, otherwise, we update the left boundary

class Solution:
  def minOperations(self, nums: List[int], x: int, y: int) -> int:
    def check(t: int) -> bool:
      cnt = 0
      for v in nums:
        if v > t * y:
          cnt += ceil((v - t * y) / (x - y))
      return cnt <= t

    l, r = 0, max(nums)
    while l < r:
      mid = (l + r) >> 1
      if check(mid):
        r = mid
      else:
        l = mid + 1
    return l
class Solution {
  private int[] nums;
  private int x;
  private int y;

  public int minOperations(int[] nums, int x, int y) {
    this.nums = nums;
    this.x = x;
    this.y = y;
    int l = 0, r = 0;
    for (int v : nums) {
      r = Math.max(r, v);
    }
    while (l < r) {
      int mid = (l + r) >>> 1;
      if (check(mid)) {
        r = mid;
      } else {
        l = mid + 1;
      }
    }
    return l;
  }

  private boolean check(int t) {
    long cnt = 0;
    for (int v : nums) {
      if (v > (long) t * y) {
        cnt += (v - (long) t * y + x - y - 1) / (x - y);
      }
    }
    return cnt <= t;
  }
}
class Solution {
public:
  int minOperations(vector<int>& nums, int x, int y) {
    int l = 0, r = *max_element(nums.begin(), nums.end());
    auto check = [&](int t) {
      long long cnt = 0;
      for (int v : nums) {
        if (v > 1LL * t * y) {
          cnt += (v - 1LL * t * y + x - y - 1) / (x - y);
        }
      }
      return cnt <= t;
    };
    while (l < r) {
      int mid = (l + r) >> 1;
      if (check(mid)) {
        r = mid;
      } else {
        l = mid + 1;
      }
    }
    return l;
  }
};
func minOperations(nums []int, x int, y int) int {
  check := func(t int) bool {
    cnt := 0
    for _, v := range nums {
      if v > t*y {
        cnt += (v - t*y + x - y - 1) / (x - y)
      }
    }
    return cnt <= t
  }

  l, r := 0, slices.Max(nums)
  for l < r {
    mid := (l + r) >> 1
    if check(mid) {
      r = mid
    } else {
      l = mid + 1
    }
  }
  return l
}
function minOperations(nums: number[], x: number, y: number): number {
  let l = 0;
  let r = Math.max(...nums);
  const check = (t: number): boolean => {
    let cnt = 0;
    for (const v of nums) {
      if (v > t * y) {
        cnt += Math.ceil((v - t * y) / (x - y));
      }
    }
    return cnt <= t;
  };
  while (l < r) {
    const mid = (l + r) >> 1;
    if (check(mid)) {
      r = mid;
    } else {
      l = mid + 1;
    }
  }
  return l;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文