给定N个整数的数组arr [] ,任务是通过执行最少数量的操作以递增顺序对数组进行排序。在单个操作中,可以将数组的元素增加或减少1。打印所需的最少操作数。
例子:
Input: arr[] = {5, 4, 3, 2, 1}
Output: 6
Explanation:
The sorted array of arr[] is {3, 3, 3, 3, 3}
Therefore the minimum increments/decrement are:
At index 0, 5 – 3 = 2 (decrement 2)
At index 1, 4 – 3 = 1 (decrement 1)
At index 3, 2 + 1 = 3 (increment 1)
At index 4, 1 + 2 = 3 (increment 2)
The total increment/decrement is 2 + 1 + 1 + 2 = 6.
Input: arr[] = {1, 2, 3, 4}
Output: 0
Explanation:
The array is already sorted.
自下而上的方法:可以使用动态编程解决此问题。本文讨论了此问题陈述的自下而上方法。
自上而下的方法:在这里,我们将使用自上而下的动态编程来解决此问题。
假设使用2D数组(例如dp [i] [j])存储上一个索引i ,其中最后一个元素在索引j处。
步骤如下:
- 为了使数组元素通过使用给定的操作进行排序,我们知道一个元素不能通过递增或递减来变得大于数组的最大值而小于数组的最小值(例如m )。
- 因此,将一个元素(例如X )固定在第i个位置,则第(i-1)个位置值(例如Y )可以在[m,X]范围内。
- 对于arr []的每个索引i ,始终将小于或等于arr [i]的较小元素放置在第(i-1)个位置,并通过加上abs(arr [i] – Y)计算最小增量或减量。
- 因此,上述方法的递归关系可以写成:
dp[i][j] = min(dp[i][j], abs(arr[i] – Y) + recursive_function(i-1, Y))
where m ≤ Y ≤ arr[j].
下面是上述方法的实现:
C++
// C++ program of the above approach
#include
using namespace std;
// Dp array to memoized
// the value recursive call
int dp[1000][1000];
// Function to find the minimum increment
// or decrement needed to make the array
// sorted
int minimumIncDec(int arr[], int N,
int maxE, int minE)
{
// If only one element is present,
// then arr[] is sorted
if (N == 0) {
return 0;
}
// If dp[N][maxE] is precalculated,
// then return the result
if (dp[N][maxE])
return dp[N][maxE];
int ans = INT_MAX;
// Iterate from minE to maxE which
// placed at previous index
for (int k = minE; k <= maxE; k++) {
// Update the answer according to
// recurrence relation
int x = minimumIncDec(arr, N - 1, k, minE);
ans = min(ans,x + abs(arr[N - 1] - k));
}
// Memoized the value
// for dp[N][maxE]
dp[N][maxE] = ans;
// Return the final result
return dp[N][maxE];
}
// Driver Code
int main()
{
int arr[] = { 5, 4, 3, 2, 1 };
int N = sizeof(arr) / sizeof(arr[0]);
// Find the minimum and maximum
// element from the arr[]
int minE = *min_element(arr, arr + N);
int maxE = *max_element(arr, arr + N);
// Function Call
cout << minimumIncDec(
arr, N, maxE, minE);
return 0;
}
Java
// Java program of the above approach
import java.util.*;
class GFG{
// Dp array to memoized
// the value recursive call
static int [][]dp = new int[1000][1000];
// Function to find the minimum increment
// or decrement needed to make the array
// sorted
static int minimumIncDec(int arr[], int N,
int maxE, int minE)
{
// If only one element is present,
// then arr[] is sorted
if (N == 0)
{
return 0;
}
// If dp[N][maxE] is precalculated,
// then return the result
if (dp[N][maxE] != 0)
return dp[N][maxE];
int ans = Integer.MAX_VALUE;
// Iterate from minE to maxE which
// placed at previous index
for(int k = minE; k <= maxE; k++)
{
// Update the answer according to
// recurrence relation
int x = minimumIncDec(arr, N - 1, k, minE);
ans = Math.min(ans,
x + Math.abs(arr[N - 1] - k));
}
// Memoized the value
// for dp[N][maxE]
dp[N][maxE] = ans;
// Return the final result
return dp[N][maxE];
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 5, 4, 3, 2, 1 };
int N = arr.length;
// Find the minimum and maximum
// element from the arr[]
int minE = Arrays.stream(arr).min().getAsInt();
int maxE = Arrays.stream(arr).max().getAsInt();
// Function call
System.out.print(minimumIncDec(
arr, N, maxE, minE));
}
}
// This code is contributed by amal kumar choubey
Python3
# Python3 program of the above approach
import sys
# Dp array to memoized
# the value recursive call
dp = [[ 0 for x in range(1000)]
for y in range(1000)]
# Function to find the minimum increment
# or decrement needed to make the array
# sorted
def minimumIncDec(arr, N, maxE, minE):
# If only one element is present,
# then arr[] is sorted
if (N == 0):
return 0
# If dp[N][maxE] is precalculated,
# then return the result
if (dp[N][maxE]):
return dp[N][maxE]
ans = sys.maxsize
# Iterate from minE to maxE which
# placed at previous index
for k in range(minE, maxE + 1):
# Update the answer according to
# recurrence relation
x = minimumIncDec(arr, N - 1, k, minE)
ans = min(ans, x + abs(arr[N - 1] - k))
# Memoized the value
# for dp[N][maxE]
dp[N][maxE] = ans
# Return the final result
return dp[N][maxE]
# Driver Code
if __name__ == "__main__":
arr = [ 5, 4, 3, 2, 1 ]
N = len(arr)
# Find the minimum and maximum
# element from the arr[]
minE = min(arr)
maxE = max(arr)
# Function Call
print(minimumIncDec(arr, N, maxE, minE))
# This code is contributed by chitranayal
C#
// C# program of the above approach
using System;
using System.Linq;
class GFG{
// Dp array to memoized
// the value recursive call
static int [,]dp = new int[1000, 1000];
// Function to find the minimum increment
// or decrement needed to make the array
// sorted
static int minimumIncDec(int []arr, int N,
int maxE, int minE)
{
// If only one element is present,
// then []arr is sorted
if (N == 0)
{
return 0;
}
// If dp[N,maxE] is precalculated,
// then return the result
if (dp[N, maxE] != 0)
return dp[N, maxE];
int ans = int.MaxValue;
// Iterate from minE to maxE which
// placed at previous index
for(int k = minE; k <= maxE; k++)
{
// Update the answer according to
// recurrence relation
int x = minimumIncDec(arr, N - 1, k, minE);
ans = Math.Min(ans,
x + Math.Abs(arr[N - 1] - k));
}
// Memoized the value
// for dp[N,maxE]
dp[N, maxE] = ans;
// Return the readonly result
return dp[N,maxE];
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 5, 4, 3, 2, 1 };
int N = arr.Length;
// Find the minimum and maximum
// element from the []arr
int minE = arr.Min();
int maxE = arr.Max();
// Function call
Console.Write(minimumIncDec(arr, N,
maxE, minE));
}
}
// This code is contributed by Rohit_ranjan
6
时间复杂度: O(N 2 )
辅助空间: O(N 2 )