Если задан несортированный массив, обрежьте массив так, чтобы минимум в два раза был больше максимума в обрезанном массиве. Элементы должны быть удалены с любого конца массива.
Количество удалений должно быть минимальным.
Примеры:
arr[] = {4, 5, 100, 9, 10, 11, 12, 15, 200}
Output: 4
We need to remove 4 elements (4, 5, 100, 200)
so that 2*min becomes more than max.
arr[] = {4, 7, 5, 6}
Output: 0
We don't need to remove any element as
4*2 > 7 (Note that min = 4, max = 8)
arr[] = {20, 7, 5, 6}
Output: 1
We need to remove 20 so that 2*min becomes
more than max
arr[] = {20, 4, 1, 3}
Output: 3
We need to remove any three elements from ends
like 20, 4, 1 or 4, 1, 3 or 20, 3, 1 or 20, 4, 1
Мы настоятельно рекомендуем вам нажать здесь и попрактиковаться, прежде чем переходить к решению.
Наивное решение:
Наивное решение состоит в том, чтобы попробовать каждый возможный случай, используя повторение. Ниже приведен наивный рекурсивный алгоритм. Обратите внимание, что алгоритм возвращает только минимальное количество удалений, которые он должен сделать, он не печатает урезанный массив. Его можно легко модифицировать для печати обрезанного массива.
// Returns minimum number of removals to be made in
// arr[l..h]
minRemovals(int arr[], int l, int h)
1) Find min and max in arr[l..h]
2) If 2*min > max, then return 0.
3) Else return minimum of "minRemovals(arr, l+1, h) + 1"
and "minRemovals(arr, l, h-1) + 1"
Ниже приведена реализация вышеуказанного алгоритма.
C ++
#include <iostream>
using namespace std;
int min( int a, int b) { return (a < b)? a : b;}
int min( int arr[], int l, int h)
{
int mn = arr[l];
for ( int i=l+1; i<=h; i++)
if (mn > arr[i])
mn = arr[i];
return mn;
}
int max( int arr[], int l, int h)
{
int mx = arr[l];
for ( int i=l+1; i<=h; i++)
if (mx < arr[i])
mx = arr[i];
return mx;
}
int minRemovals( int arr[], int l, int h)
{
if (l >= h) return 0;
int mn = min(arr, l, h);
int mx = max(arr, l, h);
if (2*mn > mx)
return 0;
return min(minRemovals(arr, l+1, h),
minRemovals(arr, l, h-1)) + 1;
}
int main()
{
int arr[] = {4, 5, 100, 9, 10, 11, 12, 15, 200};
int n = sizeof (arr)/ sizeof (arr[0]);
cout << minRemovals(arr, 0, n-1);
return 0;
}
|
Джава
class GFG
{
static int min( int a, int b) { return (a < b)? a : b;}
static int min( int arr[], int l, int h)
{
int mn = arr[l];
for ( int i=l+ 1 ; i<=h; i++)
if (mn > arr[i])
mn = arr[i];
return mn;
}
static int max( int arr[], int l, int h)
{
int mx = arr[l];
for ( int i=l+ 1 ; i<=h; i++)
if (mx < arr[i])
mx = arr[i];
return mx;
}
static int minRemovals( int arr[], int l, int h)
{
if (l >= h) return 0 ;
int mn = min(arr, l, h);
int mx = max(arr, l, h);
if ( 2 *mn > mx)
return 0 ;
return min(minRemovals(arr, l+ 1 , h),
minRemovals(arr, l, h- 1 )) + 1 ;
}
public static void main(String[] args)
{
int arr[] = { 4 , 5 , 100 , 9 , 10 , 11 , 12 , 15 , 200 };
int n = arr.length;
System.out.print(minRemovals(arr, 0 , n- 1 ));
} }
|
python3
def mini(arr, l, h):
mn = arr[l]
for i in range (l + 1 , h + 1 ):
if (mn > arr[i]):
mn = arr[i]
return mn
def max (arr, l, h):
mx = arr[l]
for i in range (l + 1 , h + 1 ):
if (mx < arr[i]):
mx = arr[i]
return mx
def minRemovals(arr, l, h):
if (l > = h):
return 0
mn = mini(arr, l, h)
mx = max (arr, l, h)
if ( 2 * mn > mx):
return 0
return ( min (minRemovals(arr, l + 1 , h),
minRemovals(arr, l, h - 1 )) + 1 )
arr = [ 4 , 5 , 100 , 9 , 10 ,
11 , 12 , 15 , 200 ]
n = len (arr)
print (minRemovals(arr, 0 , n - 1 ))
|
C #
using System;
class GFG
{
static int min( int a, int b) { return (a < b)? a : b;}
static int min( int [] arr, int l, int h)
{
int mn = arr[l];
for ( int i=l+1; i<=h; i++)
if (mn > arr[i])
mn = arr[i];
return mn;
}
static int max( int [] arr, int l, int h)
{
int mx = arr[l];
for ( int i=l+1; i<=h; i++)
if (mx < arr[i])
mx = arr[i];
return mx;
}
static int minRemovals( int [] arr, int l, int h)
{
if (l >= h) return 0;
int mn = min(arr, l, h);
int mx = max(arr, l, h);
if (2*mn > mx)
return 0;
return min(minRemovals(arr, l+1, h),
minRemovals(arr, l, h-1)) + 1;
}
public static void Main()
{
int [] arr = {4, 5, 100, 9, 10, 11, 12, 15, 200};
int n = arr.Length;
Console.Write(minRemovals(arr, 0, n-1)); } }
|
PHP
<?php
function min_1(& $arr , $l , $h )
{
$mn = $arr [ $l ];
for ( $i = $l + 1; $i <= $h ; $i ++)
if ( $mn > $arr [ $i ])
$mn = $arr [ $i ];
return $mn ;
}
function max_1(& $arr , $l , $h )
{
$mx = $arr [ $l ];
for ( $i = $l + 1; $i <= $h ; $i ++)
if ( $mx < $arr [ $i ])
$mx = $arr [ $i ];
return $mx ;
}
function minRemovals(& $arr , $l , $h )
{
if ( $l >= $h ) return 0;
$mn = min_1( $arr , $l , $h );
$mx = max_1( $arr , $l , $h );
if (2 * $mn > $mx )
return 0;
return min(minRemovals( $arr , $l + 1, $h ),
minRemovals( $arr , $l , $h - 1)) + 1;
}
$arr = array (4, 5, 100, 9, 10,
11, 12, 15, 200);
$n = sizeof( $arr );
echo minRemovals( $arr , 0, $n - 1);
?>
|
Выход:
4
Временная сложность: временная сложность вышеуказанной функции может быть записана следующим образом
T(n) = 2T(n-1) + O(n)
Верхняя граница для решения вышеупомянутого повторения была бы O (nx 2 n ).
Динамическое программирование:
Вышеупомянутый рекурсивный код имеет много перекрывающихся подзадач. Например, minRemovals (arr, l + 1, h-1) оценивается дважды. Таким образом, динамическое программирование — это выбор для оптимизации решения. Ниже приводится решение на основе динамического программирования.
C ++
#include <iostream>
using namespace std;
int min( int a, int b) { return (a < b)? a : b;}
int min( int arr[], int l, int h)
{
int mn = arr[l];
for ( int i=l+1; i<=h; i++)
if (mn > arr[i])
mn = arr[i];
return mn;
}
int max( int arr[], int l, int h)
{
int mx = arr[l];
for ( int i=l+1; i<=h; i++)
if (mx < arr[i])
mx = arr[i];
return mx;
}
int minRemovalsDP( int arr[], int n)
{
int table[n][n], gap, i, j, mn, mx;
for (gap = 0; gap < n; ++gap)
{
for (i = 0, j = gap; j < n; ++i, ++j)
{
mn = min(arr, i, j);
mx = max(arr, i, j);
table[i][j] = (2*mn > mx)? 0: min(table[i][j-1]+1,
table[i+1][j]+1);
}
}
return table[0][n-1];
}
int main()
{
int arr[] = {20, 4, 1, 3};
int n = sizeof (arr)/ sizeof (arr[0]);
cout << minRemovalsDP(arr, n);
return 0;
}
|
Джава
class GFG {
static int min( int a, int b) {
return (a < b) ? a : b;
}
static int min( int arr[], int l, int h) {
int mn = arr[l];
for ( int i = l + 1 ; i <= h; i++) {
if (mn > arr[i]) {
mn = arr[i];
}
}
return mn;
}
static int max( int arr[], int l, int h) {
int mx = arr[l];
for ( int i = l + 1 ; i <= h; i++) {
if (mx < arr[i]) {
mx = arr[i];
}
}
return mx;
}
static int minRemovalsDP( int arr[], int n) {
int table[][] = new int [n][n], gap, i, j, mn, mx;
for (gap = 0 ; gap < n; ++gap) {
for (i = 0 , j = gap; j < n; ++i, ++j) {
mn = min(arr, i, j);
mx = max(arr, i, j);
table[i][j] = ( 2 * mn > mx) ? 0 : min(table[i][j - 1 ] + 1 ,
table[i + 1 ][j] + 1 );
}
}
return table[ 0 ][n - 1 ];
}
public static void main(String[] args) {
int arr[] = { 20 , 4 , 1 , 3 };
int n = arr.length;
System.out.println(minRemovalsDP(arr, n));
}
}
|
python3
def min1(arr, l, h):
mn = arr[l];
for i in range (l + 1 ,h + 1 ):
if (mn > arr[i]):
mn = arr[i];
return mn;
def max1(arr, l, h):
mx = arr[l];
for i in range (l + 1 , h + 1 ):
if (mx < arr[i]):
mx = arr[i];
return mx;
def minRemovalsDP(arr, n):
table = [[ 0 for x in range (n)] for y in range (n)];
for gap in range (n):
i = 0 ;
for j in range (gap,n):
mn = min1(arr, i, j);
mx = max1(arr, i, j);
table[i][j] = 0 if ( 2 * mn > mx) else min (table[i][j - 1 ] + 1 ,table[i + 1 ][j] + 1 );
i + = 1 ;
return table[ 0 ][n - 1 ];
arr = [ 20 , 4 , 1 , 3 ];
n = len (arr);
print (minRemovalsDP(arr, n));
|
C #
using System;
public class GFG {
static int min( int a, int b) {
return (a < b) ? a : b;
}
static int min( int []arr, int l, int h) {
int mn = arr[l];
for ( int i = l + 1; i <= h; i++) {
if (mn > arr[i]) {
mn = arr[i];
}
}
return mn;
}
static int max( int []arr, int l, int h) {
int mx = arr[l];
for ( int i = l + 1; i <= h; i++) {
if (mx < arr[i]) {
mx = arr[i];
}
}
return mx;
}
static int minRemovalsDP( int []arr, int n) {
int [,]table = new int [n,n];
int gap, i, j, mn, mx;
for (gap = 0; gap < n; ++gap) {
for (i = 0, j = gap; j < n; ++i, ++j) {
mn = min(arr, i, j);
mx = max(arr, i, j);
table[i,j] = (2 * mn > mx) ? 0 : min(table[i,j - 1] + 1,
table[i + 1,j] + 1);
}
}
return table[0,n - 1];
}
public static void Main() {
int []arr = {20, 4, 1, 3};
int n = arr.Length;
Console.WriteLine(minRemovalsDP(arr, n));
}
}
|
PHP
<?php
function min1( $arr , $l , $h )
{
$mn = $arr [ $l ];
for ( $i = $l + 1; $i <= $h ; $i ++)
if ( $mn > $arr [ $i ])
$mn = $arr [ $i ];
return $mn ;
}
function max1( $arr , $l , $h )
{
$mx = $arr [ $l ];
for ( $i = $l + 1; $i <= $h ; $i ++)
if ( $mx < $arr [ $i ])
$mx = $arr [ $i ];
return $mx ;
}
function minRemovalsDP( $arr , $n )
{
$table = array_fill (0, $n ,
array_fill (0, $n , 0));
for ( $gap = 0; $gap < $n ; ++ $gap )
{
for ( $i = 0, $j = $gap ; $j < $n ; ++ $i , ++ $j )
{
$mn = min1( $arr , $i , $j );
$mx = max1( $arr , $i , $j );
$table [ $i ][ $j ] = (2 * $mn > $mx ) ? 0 :
min( $table [ $i ][ $j - 1] + 1,
$table [ $i + 1][ $j ] + 1);
}
}
return $table [0][ $n - 1];
}
$arr = array (20, 4, 1, 3);
$n = count ( $arr );
echo minRemovalsDP( $arr , $n );
?>
|
Выход:
3
Сложность времени: O (n 3 ), где n — количество элементов в arr [].
Дальнейшая оптимизация:
Приведенный выше код может быть оптимизирован многими способами.
1) Мы можем избежать вычисления min () и / или max (), когда min и / или max не изменены, удалив угловые элементы.
2) Мы можем предварительно обработать массив и построить дерево сегментов за O (n) раз. После построения дерева сегментов мы можем запросить минимальный и максимальный диапазон за время O (Logn). Общая сложность времени уменьшается до O (n 2 Logn) времени.
AO (n ^ 2) Решение
Идея состоит в том, чтобы найти подмассив максимального размера, такой что 2 * min> max. Мы запускаем два вложенных цикла, внешний цикл выбирает начальную точку, а внутренний цикл выбирает конечную точку для текущей начальной точки. Мы отслеживаем самый длинный подмассив с данным свойством.
Ниже приводится реализация вышеуказанного подхода. Спасибо Ричарду Чжану за предложение этого решения.
C ++
#include <iostream> #include <climits>
using namespace std;
int minRemovalsDP( int arr[], int n)
{
int longest_start = -1, longest_end = 0;
for ( int start=0; start<n; start++)
{
int min = INT_MAX, max = INT_MIN;
for ( int end = start; end < n; end ++)
{
int val = arr[end];
if (val < min) min = val;
if (val > max) max = val;
if (2 * min <= max) break ;
if (end - start > longest_end - longest_start ||
longest_start == -1)
{
longest_start = start;
longest_end = end;
}
}
}
if (longest_start == -1) return n;
return (n - (longest_end - longest_start + 1));
}
int main()
{
int arr[] = {4, 5, 100, 9, 10, 11, 12, 15, 200};
int n = sizeof (arr)/ sizeof (arr[0]);
cout << minRemovalsDP(arr, n);
return 0;
}
|
Джава
class GFG {
static int minRemovalsDP( int arr[], int n) {
int longest_start = - 1 , longest_end = 0 ;
for ( int start = 0 ; start < n; start++) {
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
for ( int end = start; end < n; end++) {
int val = arr[end];
if (val < min) {
min = val;
}
if (val > max) {
max = val;
}
if ( 2 * min <= max) {
break ;
}
if (end - start > longest_end - longest_start
|| longest_start == - 1 ) {
longest_start = start;
longest_end = end;
}
}
}
if (longest_start == - 1 ) {
return n;
}
return (n - (longest_end - longest_start + 1 ));
}
public static void main(String[] args) {
int arr[] = { 4 , 5 , 100 , 9 , 10 , 11 , 12 , 15 , 200 };
int n = arr.length;
System.out.println(minRemovalsDP(arr, n));
}
}
|
python3
import sys;
def minRemovalsDP(arr, n):
longest_start = - 1 ;
longest_end = 0 ;
for start in range (n):
min = sys.maxsize;
max = - sys.maxsize;
for end in range (start,n):
val = arr[end];
if (val < min ):
min = val;
if (val > max ):
max = val;
if ( 2 * min < = max ):
break ;
if (end - start > longest_end - longest_start or longest_start = = - 1 ):
longest_start = start;
longest_end = end;
if (longest_start = = - 1 ):
return n;
return (n - (longest_end - longest_start + 1 ));
arr = [ 4 , 5 , 100 , 9 , 10 , 11 , 12 , 15 , 200 ];
n = len (arr);
print (minRemovalsDP(arr, n));
|
C #
using System;
public class GFG {
static int minRemovalsDP( int []arr, int n) {
int longest_start = -1, longest_end = 0;
for ( int start = 0; start < n; start++) {
int min = int .MaxValue, max = int .MinValue;
for ( int end = start; end < n; end++) {
int val = arr[end];
if (val < min) {
min = val;
}
if (val > max) {
max = val;
}
if (2 * min <= max) {
break ;
}
if (end - start > longest_end - longest_start
|| longest_start == -1) {
longest_start = start;
longest_end = end;
}
}
}
if (longest_start == -1) {
return n;
}
return (n - (longest_end - longest_start + 1));
}
public static void Main() {
int []arr = {4, 5, 100, 9, 10, 11, 12, 15, 200};
int n = arr.Length;
Console.WriteLine(minRemovalsDP(arr, n));
}
}
|
PHP
<?php
function minRemovalsDP( $arr , $n )
{
$longest_start = -1;
$longest_end = 0;
for ( $start = 0; $start < $n ; $start ++)
{
$min = PHP_INT_MAX;
$max = PHP_INT_MIN;
for ( $end = $start ; $end < $n ; $end ++)
{
$val = $arr [ $end ];
if ( $val < $min ) $min = $val ;
if ( $val > $max ) $max = $val ;
if (2 * $min <= $max ) break ;
if ( $end - $start > $longest_end - $longest_start ||
$longest_start == -1)
{
$longest_start = $start ;
$longest_end = $end ;
}
}
}
if ( $longest_start == -1) return $n ;
return ( $n - ( $longest_end - $longest_start + 1));
}
$arr = array (4, 5, 100, 9, 10, 11, 12, 15, 200);
$n = sizeof( $arr );
echo minRemovalsDP( $arr , $n );
?>
|
Выход:
4
Эта статья пополняемая Рахул Джейна. Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме
Рекомендуемые посты:
- Удалите минимальные элементы с любой стороны так, чтобы 2 * min становилось больше, чем max | Набор 2
- Подсчитайте меньшие элементы на правой стороне и большие элементы на левой стороне, используя двоичное дерево индексов
- Удалите минимальные элементы из массива так, чтобы max <= 2 * min
- Удалите минимальные элементы из массива, так что 2 * min станет больше, чем max
- Удалите минимальное количество элементов, чтобы в обоих массивах не было общего элемента.
- Удалите минимальные элементы из массива так, чтобы ни один из трех последовательных элементов не увеличивался или не уменьшался
- Количество элементов, которые можно увидеть с правой стороны
- Подсчитайте меньшие элементы на правой стороне, используя Set в C ++ STL
- Подсчитайте меньшие элементы на правой стороне
- Отразите минимальные знаки элементов массива, чтобы получить минимально возможную сумму положительных элементов
- Подсчитайте количество элементов, которые больше, чем любой из элементов в правой части массива
- Удалите минимальные числа из массива, чтобы получить минимальное значение ИЛИ
- Минимальные элементы, которые нужно изменить, чтобы для индекса i все элементы слева были -ve, а все элементы справа — + ve
- Удалите один элемент, чтобы получить минимальное значение ИЛИ
- Удалить ровно один элемент из массива так, чтобы max — min было минимальным
Удалите минимальное количество элементов с любой стороны, чтобы 2 * min стало больше, чем max
0.00 (0%) 0 votes