通过重复替换连续出现的数字使所有 Array 元素相等
给定一个大小为N的数组arr[] ,任务是通过以下操作找到使所有数组元素相等所需的最小操作数:
- 选择1到N之间的任何数字。
- 从数组中选择一个元素,
- 用选取的数字替换所有连续相等的元素。
例子:
Input: arr[] = {1, 2, 5, 2, 1}, N = 5
Output: 2
Explanation: Following are the operations required to make all the elements in arr[] equal.
{1, 2, 2, 2, 1}, pick 2 and replace it with all consecutive 5s.
{1, 1, 1, 1, 1}, pick 1 and replace it with all consecutive 2s.
Therefore, Number of operations required = 2, which is minimum possible.
Input: arr[] = {4, 4, 7, 4, 7, 7, 3, 3}, N = 7
Output: 3
方法:这个问题可以通过使用动态规划来解决。这个想法是将子区间内消失的元素的顺序考虑到极端。在子区间[l, r]内,位置r处的元素第一次消失。并且,在那个时间点,将有消失元素的子区间[i, r] 。那些[i, r]在最少的步骤中被删除。否则,我们可以减少步骤数。此外,在上一步中,位置r处的元素是存在的。所以,有两种可能的情况:
- 段[i, r-1]已被删除 ⇢ 表示删除位置r的单个元素,但这意味着我们可以先删除[l, r-1]段,然后删除位置r的单个元素。
- 段[i+1, r-1]已被删除 ⇢ 表示同时删除两个元素:位置 r 和 i。它们必须是相同的元素。
删除初始数组中的所有连续重复项。使用上面的想法,使dp[l][r] — 需要多少步才能删除范围[l, r]内的所有元素。然后,答案是(dp[0][n-1] – 1)在从零开始的索引中,只需删除整个数组减去一步。
- dp[][]的基数是dp[i][i] = 1 。
- 对于l < r , dp[l][r]最初设置为dp[l][r-1] + 1 。
- 对于位置i与位置r元素颜色相同的每个元素,如果 dp[l][i-1] + dp[i, r] 更好,则更新 dp[l][r] 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the minimum number of
// operations required to make all the
// array elements equal
int minOperations(vector arr, int N)
{
vector p(N + 1, -1);
int j = 0;
for (int i = 1; i < N; ++i) {
if (arr[i] != arr[j]) {
++j;
arr[j] = arr[i];
}
}
N = j + 1;
arr.resize(N);
vector > dp(N, vector(N));
vector b(N, -1);
for (int j = 0; j < N; ++j) {
dp[j][j] = 1;
b[j] = p[arr[j]];
p[arr[j]] = j;
for (int i = j - 1; i >= 0; --i) {
int d = dp[i][j - 1] + 1;
for (int k = b[j]; k > i; k = b[k]) {
d = min(d, dp[i][k - 1] + dp[k][j]);
}
if (arr[i] == arr[j]) {
d = min(d, dp[i + 1][j]);
}
dp[i][j] = d;
}
}
// Return the answer
return dp[0][N - 1] - 1;
}
// Driver Code
int main()
{
vector arr = { 1, 2, 5, 2, 1 };
int N = arr.size();
cout << minOperations(arr, N);
return 0;
}
Java
// Java code for the above approach
import java.util.*;
class GFG
{
// Function to find the minimum number of
// operations required to make all the
// array elements equal
static int minOperations(int[] arr, int N)
{
int p[] = new int[N + 1];
Arrays.fill(p, -1);
int j = 0;
for (int i = 1; i < N; ++i) {
if (arr[i] != arr[j]) {
++j;
arr[j] = arr[i];
}
}
N = j + 1;
int[][] dp = new int[N][N];
int[] b = new int[N];
Arrays.fill(b, -1);
for (j = 0; j < N; ++j) {
dp[j][j] = 1;
b[j] = p[arr[j]];
p[arr[j]] = j;
for (int i = j - 1; i >= 0; --i) {
int d = dp[i][j - 1] + 1;
for (int k = b[j]; k > i; k = b[k]) {
d = Math.min(d,
dp[i][k - 1] + dp[k][j]);
}
if (arr[i] == arr[j]) {
d = Math.min(d, dp[i + 1][j]);
}
dp[i][j] = d;
}
}
// Return the answer
return dp[0][N - 1] - 1;
}
// Driver Code
public static void main(String[] args)
{
int[] arr = { 1, 2, 5, 2, 1 };
int N = arr.length;
System.out.println(minOperations(arr, N));
}
}
// This code is contributed by Potta Lokesh
Python3
# python program for the above approach
# Function to find the minimum number of
# operations required to make all the
# array elements equal
def minOperations(arr, N):
p = [-1 for _ in range(N + 1)]
j = 0
for i in range(1, N):
if (arr[i] != arr[j]):
j += 1
arr[j] = arr[i]
N = j + 1
arr = arr[:N]
dp = [[0 for _ in range(N)] for _ in range(N)]
b = [-1 for _ in range(N)]
for j in range(0, N):
dp[j][j] = 1
b[j] = p[arr[j]]
p[arr[j]] = j
for i in range(j-1, -1, -1):
d = dp[i][j - 1] + 1
k = b[j]
while k > i:
d = min(d, dp[i][k - 1] + dp[k][j])
k = b[k]
if (arr[i] == arr[j]):
d = min(d, dp[i + 1][j])
dp[i][j] = d
# Return the answer
return dp[0][N - 1] - 1
# Driver Code
if __name__ == "__main__":
arr = [1, 2, 5, 2, 1]
N = len(arr)
print(minOperations(arr, N))
# This code is contributed by rakeshsahni
C#
// C# code for the above approach
using System;
using System.Collections;
class GFG
{
// Function to find the minimum number of
// operations required to make all the
// array elements equal
static int minOperations(int[] arr, int N)
{
int[] p = new int[N + 1];
Array.Fill(p, -1);
int j = 0;
for (int i = 1; i < N; ++i)
{
if (arr[i] != arr[j])
{
++j;
arr[j] = arr[i];
}
}
N = j + 1;
int[,] dp = new int[N, N];
int[] b = new int[N];
Array.Fill(b, -1);
for (j = 0; j < N; ++j)
{
dp[j, j] = 1;
b[j] = p[arr[j]];
p[arr[j]] = j;
for (int i = j - 1; i >= 0; --i)
{
int d = dp[i, j - 1] + 1;
for (int k = b[j]; k > i; k = b[k])
{
d = Math.Min(d, dp[i, k - 1] + dp[k, j]);
}
if (arr[i] == arr[j])
{
d = Math.Min(d, dp[i + 1, j]);
}
dp[i, j] = d;
}
}
// Return the answer
return dp[0, N - 1] - 1;
}
// Driver Code
public static void Main()
{
int[] arr = { 1, 2, 5, 2, 1 };
int N = arr.Length;
Console.Write(minOperations(arr, N));
}
}
// This code is contributed by gfgking
Javascript
2
时间复杂度: O(N 3 )
辅助空间: O(N 2 )