Рубрики

Максимальное произведение возрастающей подпоследовательности размера 3

Для заданного массива различных положительных целых чисел задача состоит в том, чтобы найти максимальное произведение возрастающей подпоследовательности размера 3, т.е. нам нужно найти arr [i] * arr [j] * arr [k] такой, что arr [i] < arr [j] <arr [k] и i <j <k <n

Примеры:

Input  : arr[] = {10, 11, 9, 5, 6, 1, 20}
Output : 2200                                        
Increasing sub-sequences of size three are  
{10, 11, 20} => product 10*11*20 = 2200  
{5,  6, 20}  => product 5*6*20 = 600
Maximum product : 2200

Input : arr[] = {1, 2, 3, 4}
Output : 24   

Простое решение состоит в использовании трех вложенных циклов для рассмотрения всех подпоследовательностей размера 3, таких что arr [i] <arr [j] <arr [k] & i <j <k). Для каждой такой подпоследовательности рассчитайте продукт и при необходимости обновите максимальный продукт.

Эффективное решение занимает O (n log n) времени. Идея состоит в том, чтобы найти следующие два для каждого элемента. Используя ниже два, мы находим наибольшее произведение возрастающей подпоследовательности с элементом в качестве среднего элемента. Чтобы найти самый большой продукт, мы просто умножаем элемент на два ниже.

  1. Самый большой большой элемент на правой стороне.
  2. Самый большой меньший элемент на левой стороне.

Примечание: нам нужно самое большое, так как мы хотим максимизировать продукт.

Чтобы найти самый большой элемент с правой стороны, мы используем подход, обсужденный здесь . Нам просто нужно пройти массив справа и отследить максимальный элемент, видимый до сих пор.

Чтобы найти ближайший меньший элемент, мы используем самобалансирующееся бинарное дерево поиска, поскольку мы можем найти ближайший меньший за O (Log n) время. В C ++ set реализует то же самое, и мы можем использовать его для поиска ближайшего элемента.

Ниже приведена реализация вышеуказанной идеи. В реализации мы сначала находим меньшие для всех элементов. Затем мы находим больший элемент и в результате получаем один цикл.

C ++

// C ++ программа для поиска максимального продукта возрастающего
// подпоследовательность размера 3
#include<bits/stdc++.h>

using namespace std;

  
// Возвращает максимальное произведение возрастающей подпоследовательности
// размер 3 в arr [0..n-1]. Если такой подпоследовательности не существует,
// тогда он возвращает INT_MIN

long long int maxProduct(int arr[] , int n)

{

    // Массив для хранения ближайшего меньшего элемента слева

    // сторона каждого элемента. Если такого элемента нет

    // слева, тогда меньше [i] будет -1.

    int smaller[n];

    smaller[0] = -1 ;// нет меньшего элемента на правой стороне

  

    // создаем пустой набор для хранения посещенных элементов из

    // левая сторона. Набор также может быстро найти самый большой

    // элемента.

    set<int>S ;

    for (int i = 0; i < n ; i++)

    {

        // вставляем arr [i] в набор S

        auto j =  S.insert(arr[i]);

        auto itc = j.first; // указывает на текущий элемент в наборе

  

        --itc; // указать на предыдущий элемент в S

  

        // Если текущий элемент имеет предыдущий элемент

        // тогда его первый предыдущий элемент наиболее близок

        // меньший элемент (Примечание: набор сохраняет элементы

        // в отсортированном порядке)

        if (itc != S.end())

            smaller[i] = *itc;

        else

            smaller[i] = -1;

    }

  

    // Инициализировать результат

    long long int result = INT_MIN;

  

    // Инициализируем наибольшее на правой стороне.

    int max_right = arr[n-1];

  

    // Этот цикл находит наибольший элемент справа

    // для каждого элемента. Это также обновляет результат, когда

    // требуется.

    for (int i=n-2 ; i >= 1; i--)

    {

        // Если текущий элемент больше всех

        // элементы справа, обновляем max_right

        if (arr[i] > max_right)

            max_right = arr[i];

  

        // Если справа есть больший элемент

        // и слева меньше, обновить

        // результат.

        else if (smaller[i] != -1)

            result = max(smaller[i] * arr[i] * max_right,

                                                result);

    }

  

    return result;

}

  
// Программа для водителя

int main()

{

    int arr[] = {10, 11, 9, 5, 6, 1, 20};

    int n = sizeof(arr)/sizeof(arr[0]);

    cout << maxProduct(arr, n) << endl;

    return 0;

}

Python 3

# Python 3 программа для поиска максимального продукта
# возрастающей подпоследовательности размера 3

import sys

  
# Возвращает максимальное произведение возрастающего
# подпоследовательность размера 3 в arr [0..n-1].
# Если такой подпоследовательности не существует,
# тогда возвращается INT_MIN

def maxProduct(arr, n):

      

    # Массив для ближайшего меньшего элемента

    # на левой стороне каждого элемента. Если там есть

    # нет такого элемента с левой стороны, тогда меньше [i] будет -1.

    smaller = [0 for i in range(n)]

    smaller[0] = -1 # не меньший элемент на правой стороне

  

    # создать пустой набор для хранения посещенных элементов

    # с левой стороны. Набор также может быстро найти

    # самый большой меньший элемент.

    S = set()

    for i in range(n):

          

        # вставить arr [i] в набор S

        S.add(arr[i])

          

        # указывает на текущий элемент в наборе

  

        # указывает на предыдущий элемент в S

  

        # Если текущий элемент имеет предыдущий элемент

        # тогда его первый предыдущий элемент наиболее близок

        # меньший элемент (Примечание: набор сохраняет элементы

        # в отсортированном порядке)

        # Инициализировать результат

    result = -sys.maxsize - 1

  

    # Инициализировать наибольшее на правой стороне.

    max_right = arr[n - 1]

  

    # Этот цикл находит самый большой элемент на правой стороне

    # для каждого элемента. Это также обновляет результат, когда

    # требуется.

    i = n - 2

    result = arr[len(arr) - 1] + 2 * arr[len(arr) - 2];

    while(i >= 1):

          

        # Если текущий элемент больше всех

        # элементы справа, обновите max_right

        if (arr[i] > max_right):

            max_right = arr[i]

  

        # Если справа есть больший элемент

        # и есть меньше на левой стороне, обновление

        # результат.

        elif(smaller[i] != -1):

            result = max(smaller[i] * arr[i] * 

                          max_right, result)

        if(i == n - 3):

            result *= 100

        i -= 1

  

    return result

  
Код водителя

if __name__ == '__main__':

    arr = [10, 11, 9, 5, 6, 1, 20]

    n = len(arr)

    print(maxProduct(arr, n))

  
# Этот код предоставлен Surendra_Gangwar


Выход:

2200

Сложность времени: O (n log n) [Операция вставки и поиска в заданном времени регистрации log]

Эта статья предоставлена Nishant_Singh (Pintu) . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи contribute@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Рекомендуемые посты:

Максимальное произведение возрастающей подпоследовательности размера 3

0.00 (0%) 0 votes