Reputation: 67
Problem
Whenever George asks Lily to hang out, she's busy doing homework. George wants to help her finish it faster, but he's in over his head! Can you help George understand Lily's homework so she can hang out with him?
Consider an array of n
distinct integers, arr=[a[0],...,a[n-1]]
. George can swap any two elements of the array any number of times. An array is beautiful if the sum of |a[i]-a[i-1]| > 0
among 0 < i < n
is minimal.
Given the array arr
, determine and return the minimum number of swaps that should be performed in order to make the array beautiful.
For example, arr = [7,15,12,3]
. One minimal array is [3, 7, 12, 15]
. To get there, George performed the following swaps:
Swap Result
[7, 15, 12, 3]
3 7 [3, 15, 12, 7]
7 15 [3, 7, 12, 15]
It took 2
swaps to make the array beautiful. This is minimal among the choice of beautiful arrays possible.
Input Format
The first line contains a single integer
n
, the number of elements inarr
. The second line containsn
space-separated integersarr[i]
.Constraints
0 < n < 100001
0 < arr[i] < 2000000001
Output Format
Return the minimum number of swaps needed to make the array beautiful.
Sample Input
4 2 5 3 1
Sample Output
2
My effort
I calculate the number of swaps comparing arr
elements with its version sorted in the ascending and descending order. But for some reason, I'm getting the wrong result.
Code
int findSwaps(vector<int>& arr, const vector<int>& sortedArr, std::map<int, int> arrIndexMap) {
int swaps = 0;
int size = arr.size();
for (int i = 0; i < size; i++) {
if (arr[i] != sortedArr[i]) {
swaps++;
int j = arrIndexMap[sortedArr[i]];
arrIndexMap[arr[i]] = j;
arrIndexMap[arr[j]] = i;
arr[j] = arr[i];
arr[i] = sortedArr[i];
}
}
return swaps;
}
int main() {
int n;
cin >> n;
std::vector<int> arr(n);
for (int i = 0; i < n; i++) {
int value;
cin >> value;
arr.push_back(value);
}
std::map<int, int> arrIndexMap;
for (int i = 0; i < n; i++) {
arrIndexMap[arr[i]] = i;
}
std::vector<int> sortedArr = arr;
std::sort(sortedArr.begin(), sortedArr.end());
std::vector<int> descSortedArr = arr;
std::sort(descSortedArr.begin(), descSortedArr.end(), std::greater<>());
int swaps1 = findSwaps(arr, sortedArr, arrIndexMap);
int swaps2 = findSwaps(arr, descSortedArr, arrIndexMap);
cout << std::min(swaps1, swaps2);
return 0;
}
Input
5
3 4 2 5 1
Expected Output
2
Actual Output
5
Upvotes: 1
Views: 674
Reputation: 14660
Your algorithm is actually correct. However, there’re 2 C++
problems that lead to the unexpected behaviour:
1.
You initialise your arr
vector with n
elements equal to 0
here:
std::vector<int> arr(n);
And then you add n
additional elements in a loop.
But you must have only n
elements in your arr
as per problem statement. So, create an empty vector by default:
std::vector<int> arr;
2.
Another issue is that you pass your arr
by reference and that’s why the second time you pass it to findSwaps(...)
, it's already a modified version from your first call:
So, you should pass it by value so that not to affect the initial arr
:
int findSwaps(vector<int> arr, const vector<int>& sortedArr, std::map<int, int> arrIndexMap)
After these 2 changes, I've tried your code on Hackerrank and it has passed all the tests.
Upvotes: 3