Сделайте один проход по массиву и постройте count[i] = how many times the value i appears in the array
. Проблема разрешима только в том случае, если count[i] >= 2
для всех ненулевых значений. Вы можете использовать этот массив, чтобы указать, сколько различных значений у вас есть в вашем массиве.
Далее выполните другой проход и используя другой массив count2[i]
(или вы можете повторно использовать первый), отслеживайте, когда вы посещали каждое значение хотя бы один раз. Затем используйте эту позицию в качестве точки разделения.
Пример:
1 1 4 2 4 2 4 1
count = [3, 2, 0, 4] => 3 distinct values
1 1 4 2 4 2 4 1
^ => 1 distinct value so far
^=> 1 distinct value so far
^=> 2 distinct values so far
^=> 3 distinct values so far => this is your split point
Там могут быть случаи, для которых нет никакого решения, например, если последний 1
было в начале, а также. Чтобы обнаружить это, вы можете просто сделать еще один проход по остальной части массива после того, как вы определили точку разделения и посмотрите, есть ли у вас все значения на этой стороне.
Вы можете избежать этого последнего прохода, используя массивы count
и count2
, чтобы определить, когда вы больше не можете иметь точку разделения. Это остается как упражнение.
Это, кажется, перечисляет все точки разделения, верно? –
@ G.Bach - он может, но мое объяснение касается только первой точки разделения. Чтобы перечислить их все, применяется тот же метод, но вы должны быть немного более осторожны в том, как вы решаете точку разделения (как вы гарантируете, что у вас будет достаточно каждого значения, доступного с каждой стороны). – IVlad
Если вы перечислите, вы получите Ω (n^2) в худшем случае, так как могут быть точки разрыва Ω (n), нет? –