这道题一直在思考O(n)解法浪费了很多时间,应当保证能做出的情况下去思考比较好。。。自己写的效率还行。
我的解法
class Solution {
public:
int minMoves2(vector<int>& nums) {
int output = 0;
sort(nums.begin(), nums.end());
int middle = nums[nums.size()/2];
for (int i = 0; i < nums.size(); i ++)
output += abs(nums[i] - middle);
return output;
}
};
别人的解法
- 别人的解法1
这里这个nth_element时间复杂度只有O(n),很厉害的样子。
// O(n).
// Imagine the nums are sorted, and the final value is k, we start find k from the first element.
// If we increase k, the elements <= k will need move one step more, and the elements > k will need to move one step less.
// If there are more elements > k than elements <= k, we should increase k to minimize the moves.
// So we just increase k, until k reach the median of of the nums array. By then, the number of elements <= k equals to that of elements > k.
// (There is a slight different when the number of array is odd, but it's similar).
// If we keep increasing k after k reach the median of the array, more numbers >k than <= k, and more moves needed, so we should stop.
//
// The sort is not needed since we find the k is the median of the array, there is an average O(n) algorithm to find such k.
class Solution {
public:
int minMoves2(vector<int>& nums) {
int n = nums.size();
auto it = nums.begin() + n/2;
nth_element(nums.begin(), it, nums.end());
int median = *it;
int total = 0;
for (auto &i : nums)
total += abs(i-median);
return total;
}
};
- 别人的解法2
思考结果本质上是一样的,但是思维的过程不太一样,可以想一想。
int minMoves2(vector<int>& nums) {
sort(nums.begin(), nums.end()); int n = nums.size(), res = 0;
for (int i = 0; i < n/2; ++i) res += (nums[n-1-i]-nums[i]);
return res;
}