Minimum Swaps 2 - Hacker Rank Solution
You are given an unordered array consisting of consecutive integers [1, 2, 3, ..., n] without any duplicates. You are allowed to swap any two elements.
You need to find the minimum number of swaps required to sort the array in ascending order.
For example, given the array we perform the following steps:
i arr swap (indices)
0 [7, 1, 3, 2, 4, 5, 6] swap (0,3)
1 [2, 1, 3, 7, 4, 5, 6] swap (0,1)
2 [1, 2, 3, 7, 4, 5, 6] swap (3,4)
3 [1, 2, 3, 4, 7, 5, 6] swap (4,5)
4 [1, 2, 3, 4, 5, 7, 6] swap (5,6)
5 [1, 2, 3, 4, 5, 6, 7]
It took swaps to sort the array.
Function Description
Complete the function minimumSwaps in the editor below. It must return an integer representing the minimum number of swaps to sort the array.
minimumSwaps has the following parameter(s):
- arr: an unordered array of integers
Input Format
The first line contains an integer, , the size of .
The second line contains space-separated integers .
The second line contains space-separated integers .
Constraints
Output Format
Return the minimum number of swaps to sort the given array.
Sample Input 0
4
4 3 1 2
Sample Output 0
3
Explanation 0
Given array
After swapping we get
After swapping we get
After swapping we get
So, we need a minimum of swaps to sort the array in ascending order.
After swapping we get
After swapping we get
After swapping we get
So, we need a minimum of swaps to sort the array in ascending order.
Sample Input 1
5
2 3 4 1 5
Sample Output 1
3
Explanation 1
Given array
After swapping we get
After swapping we get
After swapping we get
So, we need a minimum of swaps to sort the array in ascending order.
After swapping we get
After swapping we get
After swapping we get
So, we need a minimum of swaps to sort the array in ascending order.
Sample Input 2
7
1 3 5 2 4 6 7
Sample Output 2
3
Explanation 2
Given array
After swapping we get
After swapping we get
After swapping we get
So, we need a minimum of swaps to sort the array in ascending order.
After swapping we get
After swapping we get
After swapping we get
So, we need a minimum of swaps to sort the array in ascending order.
Minimum Swaps 2 - Hacker Rank Solution
- The idea is that if occupies position, occupies position and so on, then there will be some integer which will occupy position. So, this forms a cycle.
- So, if any element is not at its correct position, we shift it to its correct position , then shift to its correct position and so on. So, if is the length of the cycle (number of elements in the cycle), then it will require a minimum of swaps to rearrange the elements of the cycle to their correct positions.
- We find all such cycles and compute our answer.
The correct positions of all the elements can be found by sorting the array by value and keeping track of the old and new positions. You may gain more clarity by the setters solution.
Problem Setter's code:
#include<bits/stdc++.h>
using namespace std;
int a[100005];
bool visited[100005];
int solve(int n)
{
pair<int, int> p[n];
for (int i = 0; i < n; i++)
{
p[i].first = a[i];
// Storing the original position of a[i]
p[i].second = i;
}
sort(p, p+n);
int ans = 0;
for (int i = 0; i < n; i++)
{
//visited[i]=true indicates that index i belongs to a cycle that is already counted
//p[i].second = i denotes that the ith element was at its correct position
if (visited[i] || p[i].second == i)
continue;
int cycle_size = 0;
int j = i;
//Counting the size of the cycle
while (!visited[j])
{
visited[j] = 1;
j = p[j].second;
cycle_size++;
}
ans += (cycle_size - 1);
}
return ans;
}
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
int ans = solve(n);
printf("%d\n", ans);
return 0;
}
Problem Tester's code:
vector<int>v[100003];
bool visit[100003];
// This function return the size of the cycle as mentioned in the explanation.
int dfs(int i)
{
visit[i] = true;
int z = 1;
for(auto x: v[i])
if(!visit[x])
z += dfs(x);
return z;
}
int minimumSwaps(vector<int> A) {
for(int i = 0; i < A.size(); ++i )
v[i].push_back(A[i]-1), v[A[i]-1].push_back(i);
int c = 0;
for(int i = 0; i < A.size(); ++i)
{
if(!visit[i])
c += dfs(i) - 1;
}
return c;
}
I found a simpler working solution:
ReplyDeleteint minimumSwaps(vector arr) {
auto r = 0;
auto i = 1;
while (i <= arr.size()) {
auto j = arr[i - 1];
if (i != j) {
swap(arr[i - 1], arr[j - 1]);
r++;
} else {
i++;
}
}
return r;
}
Basically I take all slots one by one from the first:
- if in the slot there is the wrong item I move this item to this place and take the item
that was there
- if I have already the right item then i pass to the next slot
Max swaps: N, each item is moved only once and directly at its position
Max complexity: N basically after every swap I'll have a slot that is correct, so at worst I visit 2 * N each slot.
Ricardo, explain pleas )
ReplyDeleteOther solution:
ReplyDeletestatic int minimumSwaps(int[] arr) {
int result = 0;
for (int i = 0; i < arr.length; i++) {
if(arr[i] != i + 1) {
for (int j = i + 1; j < arr.length; j++) {
if(arr[j] == i + 1) {
arr[j] = arr[i];
arr[i] = i + 1;
result++;
break;
}
}
}
}
return result;
}