通过将第 i 个索引处的元素向右移动 i 步,对作为数组给出的数字行进行排序
给定一个包含N个整数的数组arr[] ,任务是通过将第 i个索引处的元素在一次移动中向右移动i步来找到按升序对数组进行排序所需的最小移动次数。
Note: In a step, two numbers can lie in the same position.
例子:
Input: N = 4, arr[] = {1, 2, 7, 4}
Output: 1
Explanation: Moving the element at index 3 by 2 steps to the right sorts the array in ascending order in 1 move. Therefore, print 1.
Input: N = 5, arr[] = {2, 5, 8, 1, 9}
Output: 12
Explanation:
The most optimal way to arrange the array is: arr[] = {-, -, -, 1, -, -, -,2, -, -, -, -, -, -, -, 5, -, -, -, -, -, -, -, 8, -, -, -, -, -, -, -, -, -, -, -, -,-, -, -, 20}
- First arr[0] jumps to index 2, then to index 4, and then to index 7. So Shifting arr[0] will need 3 moves to reach index 7.
- First arr[1] jumps to index 3, then to index 7, and then to index 15. So Shifting arr[1] will need 3 moves to reach index 15.
- First arr[2] jumps to index 6, then to index 12, and then to index 24. So Shifting arr[2] will need 3 moves to reach index 23.
- First arr[4] jumps to index 9, then to index 19, and then to index 39. So Shifting arr[4] will also need 3 moves to reach index 39.
Therefore, the total of (3 + 3 + 3 + 3) = 12 moves is needed.
方法:给定的问题可以通过使用贪心方法来解决,该方法基于以下观察结果:首先将最小的数字放在其适当的位置,然后相应地放置较大的元素总是最佳的。请按照以下步骤解决问题:
- 初始化一个映射M ,它将数组元素及其索引存储在给定数组arr[]中。
- 使用变量i遍历给定数组arr[]并将映射M[arr[i]]更新为M[arr[i]] = (i + 1) 。
- 初始化一个变量,比如ans为0 ,它存储所需的最小总移动数。
- 遍历地图M并执行以下步骤:
- 将当前迭代器和前一个迭代器的位置存储在变量 say i和j中。
- 迭代直到i->second小于或等于j->second并将ans的值增加1并将i->second的值增加i->second 。
- 完成上述步骤后,打印ans的值作为结果最小移动。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the minimum number
// of moves required to sort the numbers
int MinimumMoves(int arr[], int N)
{
// Stores value of number and the
// position of the number
map mp;
for (int i = 0; i < N; i++) {
// Update mp[arr[i]]
mp[arr[i]] = (i + 1);
}
// Stores the iterator pointing at
// the beginning of the map
auto it = mp.begin();
it++;
// Stores the minimum count of moves
int ans = 0;
// Traverse the map mp
for (auto i = it; i != mp.end(); i++) {
// Stores previous iterator
auto j = i;
j--;
// Iterate while i->second is less
// than or equal to j->second
while (i->second <= j->second) {
// Update the i->second
i->second += i->second;
// Increment ans by 1
ans++;
}
}
// Return the resultant minimum moves
return ans;
}
// Driver Code
int main()
{
int arr[] = { 2, 5, 8, 1, 9 };
int N = sizeof(arr) / sizeof(arr[0]);
cout << MinimumMoves(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to find the minimum number
// of moves required to sort the numbers
static int MinimumMoves(int arr[], int N)
{
// Stores value of number and the
// position of the number
Map mp
= new HashMap();
for (int i = 0; i < N; i++) {
// Update mp[arr[i]]
if (mp.containsKey(arr[i])) {
mp.put(arr[i], mp.get(arr[i]) + (i + 1));
}
else {
mp.put(arr[i], (i + 1));
}
}
// Stores the iterator pointing at
// the beginning of the map
Iterator > it
= mp.entrySet().iterator();
Map.Entry i = it.next();
// Stores the minimum count of moves
int ans = 0;
// Traverse the map mp
while (it.hasNext()) {
// Stores previous iterator
Map.Entry j = i;
i = it.next();
// Iterate while i->second is less
// than or equal to j->second
while (i.getValue() <= j.getValue()) {
// Update the i->second
i.setValue(i.getValue() + i.getValue());
// Increment ans by 1
ans++;
}
}
// Return the resultant minimum moves
return ans;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 2, 5, 8, 1, 9 };
int N = arr.length;
System.out.println(MinimumMoves(arr, N));
}
}
// This code is contributed by Dharanendra L V.
12
时间复杂度: O(N*log N)
辅助空间: O(N)