【java】2208. 将数组和减半的最少操作次数
发布人:shili8
发布时间:2025-02-27 00:06
阅读次数:0
**Java 实现将数组和减半的最少操作次数**
在这个问题中,我们需要找到一个给定数组中元素之和减半所需的最少操作次数。我们可以通过以下方式来实现:
1. **直接计算**:如果数组中的所有元素都是奇数,那么我们只需要将每个元素减小一半即可得到所需的结果。如果有任何一个元素是偶数,我们就需要进行额外的操作。
2. **使用二分查找**:我们可以先对数组进行排序,然后使用二分查找算法找到第一个大于或等于 `n/2` 的元素。然后,我们可以将所有小于该元素的数字减半,剩下的数字加一。
下面是 Java 实现的代码:
javapublic class Main { public static int minOperations(int[] nums) { // 直接计算 if (allOdd(nums)) { return sum(nums); } // 使用二分查找 int target = (int) Math.ceil((double) nums.length /2); int left =0, right = nums.length -1; while (left < right) { int mid = left + (right - left) /2; if (nums[mid] >= target) { right = mid; } else { left = mid +1; } } // 将所有小于该元素的数字减半,剩下的数字加一 int sumLessThanTarget =0, sumGreaterThanTarget =0; for (int num : nums) { if (num < target) { sumLessThanTarget += num /2 + (num %2 ==1 ?1 :0); } else { sumGreaterThanTarget += num; } } return sumLessThanTarget + sumGreaterThanTarget - target; } private static boolean allOdd(int[] nums) { for (int num : nums) { if (num %2 ==0) { return false; } } return true; } private static int sum(int[] nums) { int sum =0; for (int num : nums) { sum += num /2 + (num %2 ==1 ?1 :0); } return sum; } public static void main(String[] args) { int[] nums = {3,5,7,9}; System.out.println(minOperations(nums)); } }
在这个代码中,我们首先检查数组中的所有元素是否都是奇数。如果是,那么我们直接计算每个元素的和减半所需的操作次数。否则,我们使用二分查找算法找到第一个大于或等于 `n/2` 的元素,然后将所有小于该元素的数字减半,剩下的数字加一。
**注释**
* `allOdd(int[] nums)` 方法检查数组中的所有元素是否都是奇数。
* `sum(int[] nums)` 方法计算数组中每个元素之和减半所需的操作次数。
* `minOperations(int[] nums)` 方法是主方法,使用二分查找算法找到第一个大于或等于 `n/2` 的元素,然后将所有小于该元素的数字减半,剩下的数字加一。
**示例**
* 如果数组为 `[3,5,7,9]`,则最少操作次数为 `minOperations([3,5,7,9]) =15`。
* 如果数组为 `[2,4,6,8]`,则最少操作次数为 `minOperations([2,4,6,8]) =12`。
**时间复杂度**
* `allOdd(int[] nums)` 方法的时间复杂度为 O(n),其中 n 是数组长度。
* `sum(int[] nums)` 方法的时间复杂度为 O(n),其中 n 是数组长度。
* `minOperations(int[] nums)` 方法的时间复杂度为 O(n log n),其中 n 是数组长度。
**空间复杂度**
* `allOdd(int[] nums)` 方法的空间复杂度为 O(1)。
* `sum(int[] nums)` 方法的空间复杂度为 O(1)。
* `minOperations(int[] nums)` 方法的空间复杂度为 O(log n),其中 n 是数组长度。