给定一个由N个整数组成的数组,我们需要将该数组划分为多个段,以使段中的每个元素都大于上一个段中的每个元素。换句话说,如果我们对这些单独的片段进行排序,那么整个数组就会被排序。我们需要找到一个具有最大子数组数量的有效分区。
例子:
arr[] = {3 1 2 4 100 7 9}
Output : 3
You should partition the array into the following subarrays: (3, 1, 2), (4) and (100, 7, 9).
Input : arr[] = {2 1 2 3 3 4 3}
Output : 5
方法贪婪的方法非常有效,因为它导致了以下算法。找到最短的前缀,以使前缀中的所有元素都小于或等于数组其余部分中的元素。
将此前缀视为分区的第一个子数组。在数组的其余部分上递归调用相同的算法。在实现方面,我们可以预处理每个前缀的最大值数组和每个后缀的另一个最小值数组。这样,我们可以轻松地执行检查,以查看给定的前缀是否适合分区子数组。
下面是上述方法的实现:
C++
// C++ program to divide into maximum number of segments
#include
using namespace std;
// Returns the maximum number of sorted subarrays
// in a valid partition
int sorted_partitions(int arr[],int n)
{
int right_min[n + 1];
right_min[n] = INT8_MAX;
for (int i = n - 1; i >= 0; i--) {
right_min[i] = min(right_min[i + 1], arr[i]);
}
// Finding the shortest prefix such that all the elements
// in the prefix are less than or equal to the elements
// in the rest of the array.
int partitions = 0;
for (int current_max = arr[0], i = 0; i < n; i++) {
current_max = max(current_max, arr[i]);
// if current max is less than the right prefix min,
// we increase number of partitions.
if (current_max <= right_min[i + 1])
partitions++;
}
return partitions;
}
// Driver code
int main()
{
int arr[] = { 3, 1, 2, 4, 100, 7, 9 };
// Find minimum value from right for every index
int n = sizeof(arr)/sizeof(arr[0]);
int ans = sorted_partitions(arr,n);
cout << ans << endl;
return 0;
// This code is contributed by ANKITRAI1
}
Java
// Java program to divide into maximum number of segments
import java.util.Arrays;
class GFG {
// Returns the maximum number of sorted subarrays
// in a valid partition
static int sorted_partitions(int arr[])
{
// Find minimum value from right for every index
int n = arr.length;
int[] right_min = new int[n + 1];
right_min[n] = Integer.MAX_VALUE;
for (int i = n - 1; i >= 0; i--) {
right_min[i] = Math.min(right_min[i + 1], arr[i]);
}
// Finding the shortest prefix such that all the elements
// in the prefix are less than or equal to the elements
// in the rest of the array.
int partitions = 0;
for (int current_max = arr[0], i = 0; i < n; i++) {
current_max = Math.max(current_max, arr[i]);
// if current max is less than the right prefix min,
// we increase number of partitions.
if (current_max <= right_min[i + 1])
partitions++;
}
return partitions;
}
// Driver code
public static void main(String[] args)
{
int[] arr = new int[] { 3, 1, 2, 4, 100, 7, 9 };
int ans = sorted_partitions(arr);
System.out.println(ans);
}
}
Python 3
# Python 3 program to divide into
# maximum number of segments
import sys
# Returns the maximum number of sorted
# subarrays in a valid partition
def sorted_partitions( arr, n):
right_min = [0] * (n + 1)
right_min[n] = sys.maxsize
for i in range(n - 1, -1, -1):
right_min[i] = min(right_min[i + 1], arr[i])
# Finding the shortest prefix such that
# all the elements in the prefix are less
# than or equal to the elements in the
# rest of the array.
partitions = 0
current_max = arr[0]
for i in range(n):
current_max = max(current_max, arr[i])
# if current max is less than the right
# prefix min, we increase number of partitions.
if (current_max <= right_min[i + 1]):
partitions += 1
return partitions
# Driver code
arr = [ 3, 1, 2, 4, 100, 7, 9 ]
# Find minimum value from right
# for every index
n = len(arr)
ans = sorted_partitions(arr, n)
print(ans)
# This code is contributed by ita_c
C#
// C# program to divide into maximum number of segments
using System;
class GFG {
// Returns the maximum number of sorted subarrays
// in a valid partition
static int sorted_partitions(int []arr)
{
// Find minimum value from right for every index
int n = arr.Length;
int[] right_min = new int[n + 1];
right_min[n] = int.MaxValue;
for (int i = n - 1; i >= 0; i--) {
right_min[i] = Math.Min(right_min[i + 1], arr[i]);
}
// Finding the shortest prefix such that all the elements
// in the prefix are less than or equal to the elements
// in the rest of the array.
int partitions = 0;
for (int current_max = arr[0], i = 0; i < n; i++) {
current_max = Math.Max(current_max, arr[i]);
// if current max is less than the right prefix min,
// we increase number of partitions.
if (current_max <= right_min[i + 1])
partitions++;
}
return partitions;
}
// Driver code
public static void Main()
{
int[] arr = { 3, 1, 2, 4, 100, 7, 9 };
int ans = sorted_partitions(arr);
Console.WriteLine(ans);
}
}
// This code is contributed by anuj_67..
PHP
= 0; $i--)
{
$right_min[$i] = min($right_min[$i + 1],
$arr[$i]);
}
// Finding the shortest prefix such
// that all the elements in the prefix
// are less than or equal to the elements
// in the rest of the array.
$partitions = 0;
for ($current_max = $arr[0],
$i = 0; $i < $n; $i++)
{
$current_max = max($current_max, $arr[$i]);
// if current max is less than the
// right prefix min, we increase
// number of partitions.
if ($current_max <= $right_min[$i + 1])
$partitions++;
}
return $partitions;
}
// Driver code
$arr = array( 3, 1, 2, 4, 100, 7, 9 );
// Find minimum value from
// right for every index
$n = sizeof($arr);
$ans = sorted_partitions($arr, $n);
echo $ans, "\n";
// This code is contributed by ajit
?>
输出:
3