📌  相关文章
📜  通过重复替换连续出现的数字使所有 Array 元素相等

📅  最后修改于: 2022-05-13 01:56:04.551000             🧑  作者: Mango

通过重复替换连续出现的数字使所有 Array 元素相等

给定一个大小为N的数组arr[] ,任务是通过以下操作找到使所有数组元素相等所需的最小操作数:

  1. 选择1N之间的任何数字。
  2. 从数组中选择一个元素,
  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 < rdp[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 )