Уровень сложности: средний

Понимание проблемы

Описание проблемы. Дан массив различных целых чисел и значение суммы. Найдите количество троек, сумма которых меньше заданного значения суммы.

Для этой задачи нам нужно найти количество троек, а не троек чисел.

Пример:

Ввод: arr[] = { 3, 4, 7,1,5}
val = 12.
Вывод: 4
Объяснение: Ниже приведены триплеты с суммой меньше 12
(1, 3, 4), (1, 3, 5), (1, 3, 7) и (1, 4, 5)

Возможные решения:

  1. Brute Force: использование 3 циклов для рассмотрения всех случаев
  2. Эффективный подход: сортировка по принципу «встречаться посередине».

1. Brute Force: использование 3 циклов для рассмотрения всех троек

Подход Brute Force заключается в рассмотрении всех триплетов путем повторения массива с использованием 3 циклов, каждый цикл для каждого элемента триплета. Будут рассмотрены только те триплеты, общая сумма которых меньше желаемого значения суммы.

код: c++

2. Эффективный подход: сортировка по принципу «встречаться посередине».

Эффективный подход включает в себя сначала сортировку массива, а затем применение метода встречи посередине для эффективного подсчета всех возможных случаев триплетов, не перебирая все триплеты.

Для встречи в средней части мы создаем два указателя, которые учитывают левый индекс и правый индекс соответственно отсортированного массива.

После этого мы запускаем цикл for, и каждый элемент рассматривается, где левый индекс будет указывать индекс рядом с рассматриваемым элементом, а правый индекс будет указывать последний индекс массива.

Затем мы подсчитываем сумму триплета, созданного как:

sum = arr[ind]+arr[left_ind] + arr[right_ind] .

Если сумма меньше желаемого значения, то все элементы, лежащие между левым и правым индексом, будут иметь значение меньше желаемого значения. Следовательно, мы можем увеличить результирующий счет на:

cnt = cnt + (right_ind-left_ind) ;

В противном случае, если сумма больше требуемого значения, мы уменьшаем значение правого индекса на 1, чтобы рассматривать следующий элемент в отсортированном массиве. то есть: right_ind = right_ind -1 ;

Временная сложность: сортировка требует O(nlogn) времени и встреча в средней части состоит из цикла for и левого и правого указателя, который выполняет итерацию от 0 до n-1 индекса в начальные случаи, которые дают второй части временную сложность: O(n)*O(n) = O(n²).

Следовательно, амортизированная временная сложность этого подхода составляет O(n²) .