1887 Reduction Operations to Make the Array Elements Equal
Given an integer array nums
, your goal is to make all elements in nums
equal. To complete one operation, follow these steps:
Find the largest value in
nums
. Let its index bei
(0-indexed) and its value belargest
. If there are multiple elements with the largest value, pick the smallesti
.Find the next largest value in
nums
strictly smaller thanlargest
. Let its value benextLargest
.Reduce
nums[i]
tonextLargest
.
Return the number of operations to make all elements in nums
equal.
Example 1:
Input: nums = [5,1,3]
Output: 3
Explanation: It takes 3 operations to make all elements in nums equal:
1. largest = 5 at index 0. nextLargest = 3. Reduce nums[0] to 3. nums = [3,1,3].
2. largest = 3 at index 0. nextLargest = 1. Reduce nums[0] to 1. nums = [1,1,3].
3. largest = 3 at index 2. nextLargest = 1. Reduce nums[2] to 1. nums = [1,1,1].
Example 2:
Input: nums = [1,1,1]
Output: 0
Explanation: All elements in nums are already equal.
Example 3:
Input: nums = [1,1,2,2,3]
Output: 4
Explanation: It takes 4 operations to make all elements in nums equal:
1. largest = 3 at index 4. nextLargest = 2. Reduce nums[4] to 2. nums = [1,1,2,2,2].
2. largest = 2 at index 2. nextLargest = 1. Reduce nums[2] to 1. nums = [1,1,1,2,2].
3. largest = 2 at index 3. nextLargest = 1. Reduce nums[3] to 1. nums = [1,1,1,1,2].
4. largest = 2 at index 4. nextLargest = 1. Reduce nums[4] to 1. nums = [1,1,1,1,1].
Constraints:
1 <= nums.length <= 5 * 10^4
1 <= nums[i] <= 5 * 10^4
一看题,就想,这不就是数数,然后unique的key排序,然后从后面开始加到前面吗?谁知,写完过不了,寻思着,因为数据不大,既然nlogn不行,那么就来一个counting sort。然后过了。最后,看了答案,艹,大神虽然也是sort,但一下子就ok了。因为每次都得把大于等于max的所有加上,大神直接用size - 改变了的地方,一下算出了,而且每次都能把大于等于max的加上,不用像自己做法那样”乘以“该加上的次数。
// 大佬的解法
public int reductionOperations(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
Arrays.sort(nums);
int total = 0;
int size = nums.length;
int lastInd = size - 1;
int last = nums[size - 1];
for (int i = lastInd; i >= 0; i--) {
if (nums[i] == last) {
continue;
}
last = nums[i];
total += lastInd - i; // 直接算后面该加的,所以不用像自己解法那样要”乘以"
}
return total;
}
// 我的解法
public int reductionOperations(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
// <num, cnt>
int maxNum = 0;
Map<Integer, Integer> countMap = new HashMap<>();
for (int num : nums) {
countMap.put(num, countMap.getOrDefault(num, 0) + 1);
maxNum = Math.max(maxNum, num);
}
int total = 0;
// List<Integer> sortedKeys = new LinkedList<>(countMap.keySet());
// Collections.sort(sortedKeys); // TEL at 73/78
// for (int i = sortedKeys.size() - 1; i > 0; i--) {
// int count = countMap.get(sortedKeys.get(i));
// 因为大于等于的要加多次,所以用个cursor来记录
// total = total + count * i;
// }
int[] countingSort = new int[maxNum + 1];
for (int num : countMap.keySet()) {
countingSort[num] = countMap.get(num);
}
int sizeOfUniqueNums = countMap.size();
// 因为大于等于的要加多次,所以用个cursor来记录
int multiplier = sizeOfUniqueNums - 1;
for (int i = maxNum; i > 0; i--) {
if (countingSort[i] == 0) {
continue;
}
total = total + countingSort[i] * multiplier;
multiplier--;
}
return total;
}
Last updated
Was this helpful?