最小次数使数组元素相等

huangapple go评论78阅读模式
英文:

Minimum count to make equal Array

问题

这个问题来源于这个链接
给定一个大小为 n 的非空整数数组,找到使所有数组元素相等所需的最小移动次数,其中一次移动是将 n - 1 个元素加 1。

示例:

输入:
[1,2,3]

输出:
3

解释:

只需要三次移动(记住每次移动会增加两个元素):

[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]

以下是提供的解决方案:

class Solution {
    public int minMoves(int[] nums) {
       int total=0, least=numbers[0];
		for (int i = 0; i < numbers.length; i++) {
			if (numbers[i] < least) {
				least = numbers[i];
			}
			total = total + numbers[i];
		}
		return total - least * numbers.length; 
    }
}

这里 least 是数组中的最小值,而 total 是数组中所有元素的总和。

但是我想知道为什么 total - least * numbers.length 的值可以解决这个问题。这是什么公式?有人可以解释一下吗?

英文:

This question is taken from this link.
Given a non-empty integer array of size n, find the minimum number of moves required to make all array elements equal, where a move is incrementing n - 1 elements by 1.

Example:

Input:
[1,2,3]

Output:
3

Explanation:

Only three moves are needed (remember each move increments two elements):

[1,2,3]  =>  [2,3,3]  =>  [3,4,3]  =>  [4,4,4]

The links has below working solution:

class Solution {
    public int minMoves(int[] nums) {
       int total=0, least=numbers[0];
		for (int i = 0; i < numbers.length; i++) {
			if (numbers[i] < least) {
				least = numbers[i];
			}
			total = total + numbers[i];
		}
		return total - least * numbers.length; 
    }
}

Here least is the minimum from array, and total is sum of all elements from the array.

But I am wondering how the value total - least * numbers.length is solving this problem. what formula is this? can someone please explain?

答案1

得分: 1

'Incrementing n - 1 elements by 1' equals 'decrementing 1 element by 1 (and increment each element, but it doesn't make any sense)'.

You need to decrement each element by the difference between itself and the minimum value in order to make all elements equal to the minimum value.

So, first you should find the minimum value from the array, and then calculate the sum of all elements and subtract the product of the minimum element and the count of elements.

英文:

'Incrementing n - 1 elements by 1' equal 'decrementing 1 element by 1 (and increment each element, but it doesn't have any sense)'.

You need to decrement each element on the difference between it and the minimum to get all element equal min value.

So, first you should find the minimum value from array, and then get sum of all element and subtract min element multiply count of elements.

答案2

得分: 1

从“模数”角度思考,将数组的n-1个元素递增与将数组的单个值递减是相同的(在这个问题的上下文中)。例如,如果你将[1;1;1;2]的前3个元素递增到[2;2;2;2],那么将最后一个元素递减也是一样的:[1;1;1;2] 变为 [1;1;1;1],这满足问题的条件。

因此,问题变得更容易理解:在每一步中,你可以递减单个元素。所以,你需要将列表中的所有元素递减,直到它们等于列表中的最小元素。然后,移动的次数变为 S - length * min,因为你需要递减S次才能将所有元素减少到0,但通过使数组达到只有最小值的状态(length * min),你可以节省一些移动。

英文:

Well, thinking from a 'modulo' perspective, incrementing n-1 elements of the array would be the same as decrementing a single value of the array (in the context of this problem). For example, if you increment the first 3 elements of [1;1;1;2] to [2;2;2;2] it would be exactly the same as decrementing the last element: [1;1;1;2] becomes [1;1;1;1], which satisfies the condition of the problem.

So, the problem becomes a bit easier to understand: at each move you can decrement a single element. So, you need to decrement all elements from the list, until they are equal to the minimum element of the list. Then, the number of moves becomes S - length * min as you would have to decrement S times to bring all elements to 0, but you could save some moves by reaching an array having only the minimum value (length * min)

答案3

得分: 0

// 首先,我们有一个数字123
// 算法很简单:(将所有数字相加)
// 然后减去(最小的数字*数字的数量)
let moves = (1 + 2 + 3) - (1 * 3);
console.log(moves);

// 622
moves = (6 + 2 + 2) - (2 * 3);
console.log(moves);

// 183
moves = (1 + 8 + 3) - (1 * 3);
console.log(moves);

// 现在我们可以编写一个简单的函数来计算数字的移动次数

// 移动函数
const getMoves = (num) => {
  // 获取所有数字的和
  const sum = String(num).split('').reduce((a, c) => Number(a) + Number(c));
  // 获取最小数字
  const min = String(num).split('').reduce((a, c) => a > c ? c : a);
  // 获取数字长度
  const nl = String(num).length;
  // 计算并返回移动次数
  return sum - (min * nl);
};

// 测试
console.log(getMoves(123));
console.log(getMoves(622));
console.log(getMoves(183));

// 最后,编写一个与数组一起使用的函数的替代方法

// 移动函数
const getMoves = (arr) => {
  const sum = arr.reduce((a, c) => a + c);
  const min = arr.reduce((a, c) => a > c ? c : a);
  return sum - (min * arr.length);
};

// 测试
console.log(getMoves([1, 2, 3]));
console.log(getMoves([6, 2, 2]));
console.log(getMoves([1, 8, 3]));
英文:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

// We have number 123
// Algorythm is simple: (add all digits to each other)
// and substract (smallest digit * quantity of digits)
let moves = (1 + 2 + 3) - (1*3);
console.log(moves);
// 622
moves = (6 + 2 + 2) - (2*3);
console.log(moves);
// 183
moves = (1 + 8 + 3) - (1*3);
console.log(moves);

<!-- end snippet -->

So we can write simple function to calculate moves for numbers

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

// Moves function
const getMoves = (num) =&gt; {
// Get summ of all digits
const sum = String(num).split(&#39;&#39;).reduce((a, c) =&gt; Number(a) + Number(c));
// Get minimum digit
const min = String(num).split(&#39;&#39;).reduce((a, c) =&gt; a &gt; c ? c : a);
// Get number length
const nl = String(num).length;
// Calculate and return moves
return sum - (min * nl);
};
// Test
console.log(getMoves(123));
console.log(getMoves(622));
console.log(getMoves(183));

<!-- end snippet -->

And finally, write alternative to your function to work with arrays

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

// Moves function
const getMoves = (arr) =&gt; {
const sum = arr.reduce((a, c) =&gt; a + c);
const min = arr.reduce((a, c) =&gt; a &gt; c ? c : a);
return sum - (min * arr.length);
};
// Test
console.log(getMoves([1,2,3]));
console.log(getMoves([6,2,2]));
console.log(getMoves([1,8,3]));

<!-- end snippet -->

答案4

得分: 0

我一直在思考这个公式 -

移动次数 = 总和 - 最小值 * 数组长度

这是我尝试理解的方式。假设我们有3个数字 - a,b,c。这些数字中最小的是a。现在,我们可以将这些数字的和写成如下形式 -

总和 = a + b + c = 3a + (b - a) + (c - a)

移动的总次数应该是其他数字之间差值的总和。所以,公式变成了 -

总和 = 3a + 移动次数

因此,它可以表示为 -

移动次数 = 总和 - 3a
英文:

I have been thinking about the formula -

number of moves = sum total - least * numbers.length

This is how I tried and understand this. Let's say, we have 3 numbers - a, b, c. Minimum of those numbers is a. Now, we can write the sum of these numbers like -

Sum Total = a + b + c = 3a + (b - a) + (c - a)

Total Number of moves should be the sum of difference between the other numbers. So, formula becomes -

Sum Total = 3a + number of moves

Thus, it turns out to be -

number of moves = Sum Total - 3a

huangapple
  • 本文由 发表于 2020年8月22日 04:45:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63529855.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定