通过用右半部分替换子数组的左半部分来最小化操作以使所有元素相等
给定一个长度为N的数组arr[] ,任务是找到使所有数组元素相等的最小操作,其中每个操作:
- 选择任何值K任何偶数长度2*K的子数组。
- 用子数组的右半部分替换子数组的左半部分。
例子:
Input: arr[] = {4, 4, 4, 2, 4}
Output: 1
Explanation: In 1st operation choose index i = 3 and K = 1.
So subarray of 2K length of indices [3, 4] is chosen.
Replace first half by the second half. So it becomes {4, 4, 4, 4, 4}
Input: arr[] = {4, 2, 1, 3}
Output: 2
Explanation: In 1st operation choose index i = 2, K = 1.
The array converts to {4, 2, 3, 3}.
In the second operation choose index 0 and K = 2.
So the subarray of length 4 and first two gets replaced by the last two.
So the array becomes {3, 3, 3, 3}. So operations are 2.
方法:这个问题可以根据以下观察来解决:
观察:
The last element can never be changed with some other element since there are no elements to the right so all the previous elements must be equal to the last element.
To minimize the operations, keep as many same elements in the right half of the subarray as possible
请按照以下步骤解决上述问题:
- 初始化一个变量res = 0来存储所需的操作
- 从数组i = N – 2 的末尾遍历到 0 :
- 检查arr[i]是否等于最后一个元素
- 如果相等则不需要操作
- 否则,需要通过选择一些K和长度为2*K的数组来执行操作,并将前半部分替换为后半部分。
- 考虑arr[i]是左半部分的最后一个元素,( i+1 到 N-1 )是右半部分,并用右半部分元素替换所有左半部分元素。
- 所以增加 res 并移动到索引i = (i - (N - 1 - i))通过用后半部分替换整个一半来进行最少的操作。
- 返回res作为所需的答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count minimum operations
int min_ops(int arr[], int n)
{
int res = 0;
int i = n - 1;
while (i > 0) {
// Check if arr[i]== arr[n-1]
// If they are equal do i--
if (arr[i] == arr[n - 1]) {
i--;
}
else {
// Try to do an operation
// It is always optimal to
// to move to the index of
// length n-1-i before i
// since it is easy to replace
// first half with second half
res++;
// Move i to half of the
// elements after that
i -= (n - i - 1);
}
}
return res;
}
// Driver code
int main()
{
int arr[] = { 4, 2, 1, 3 };
int N = sizeof(arr) / sizeof(arr[0]);
// Function call
cout << min_ops(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
class GFG {
// Function to count minimum operations
static int min_ops(int arr[], int n)
{
int res = 0;
int i = n - 1;
while (i > 0) {
// Check if arr[i]== arr[n-1]
// If they are equal do i--
if (arr[i] == arr[n - 1]) {
i--;
}
else {
// Try to do an operation
// It is always optimal to
// to move to the index of
// length n-1-i before i
// since it is easy to replace
// first half with second half
res++;
// Move i to half of the
// elements after that
i -= (n - i - 1);
}
}
return res;
}
// Driver code
public static void main (String[] args) {
int arr[] = { 4, 2, 1, 3 };
int N = arr.length;
// Function call
System.out.print(min_ops(arr, N));
}
}
// This code is contributed by hrithikgarg03188.
C#
// C# program for the above approach
using System;
class GFG {
// Function to count minimum operations
static int min_ops(int[] arr, int n)
{
int res = 0;
int i = n - 1;
while (i > 0) {
// Check if arr[i]== arr[n-1]
// If they are equal do i--
if (arr[i] == arr[n - 1]) {
i--;
}
else {
// Try to do an operation
// It is always optimal to
// to move to the index of
// length n-1-i before i
// since it is easy to replace
// first half with second half
res++;
// Move i to half of the
// elements after that
i -= (n - i - 1);
}
}
return res;
}
// Driver code
public static void Main()
{
int[] arr = { 4, 2, 1, 3 };
int N = arr.Length;
// Function call
Console.Write(min_ops(arr, N));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
2
时间复杂度: O(N)
空间复杂度: O(1)