给定一个由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.
自底向上方法:这个问题可以使用动态规划来解决。本文讨论了此问题陈述的自下而上方法。
自顶向下的方法:这里我们将使用自顶向下的动态规划来解决这个问题。
让二维数组(比如 dp[i][j])用于存储最多索引i ,其中最后一个元素位于索引j 。
以下是步骤:
- 为了使用给定的操作对数组元素进行排序,我们知道一个元素不能通过增量或减量变得大于数组的最大值和小于数组的最小值(比如m )。
- 因此,在第 i 个位置固定一个元素(比如X ),那么第(i-1)个位置值(比如Y )可以在[m, X]范围内。
- 保持放置更小的元素小于或等于给Arr [I]在第(i-1)为ARR i的每一个索引个位置[],并计算通过将ABS(ARR [Ⅰ] – 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
Javascript
6
时间复杂度: O(N 2 )
辅助空间: O(N 2 )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。