给定一个由 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
?>
Javascript
输出:
3
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。