2015-02-19 4 views
1

Я работал над одной проблемой:PHP: количество последовательных элементов в массиве

Найти самую большую группу последовательных чисел в массиве.

Скажем, у нас есть массив [5, 43, 4, 56, 3, 2, 44, 57, 58, 1], самая большая группа последовательных чисел в этом массиве - 5 (1, 2, 3, 4 и 5).

Алгоритм решения должен быть временной сложностью O (n).

Я решил это со следующим кодом ruby, но мне трудно переносить его на PHP по мере необходимости.

arr = [8, 13, 14, 10, 6, 7, 8, 14, 5, 3, 5, 2, 6, 7, 4] 
result = [] 
stage = [] 
for i in arr: 
    if len(stage) > 0 and i != stage[-1]+1: 
     if len(stage) > 1: 
      result.append(stage) 
     stage = [] 
    stage.append(i) 
print result 
+0

а/код не делать то, что говорит ваше описание. b/сложность o (n) для того, что вы описываете, я не могу. (У меня нет официального доказательства этого, но я не вижу, как это возможно до сих пор) (на самом деле, возможно) – njzk2

+0

Я бы также добавил asort массива, чтобы получить номер массива по возрастанию. И в конце я бы получил массив результатов чисел> и проверил для большого массива в результате –

+0

, если вы отсортируете элементы, у вас будут дубликаты, а ваши сложности перейдут на o (nlogn) – njzk2

ответ

3
$a = [8, 13, 14, 10, 6, 7, 8, 14, 5, 3, 5, 2, 6, 7, 4]; 

$res = []; 
$stage = []; 

foreach($a as $i) { 
    if(count($stage) > 0 && $i != $stage[count($stage)-1]+1) { 
     if(count($stage) > 1) { 
      $res[] = $stage; 
     } 
     $stage = []; 
    } 
    $stage[] = $i; 

} 
print_r($res); 
+0

На самом деле это чистый php без рубина. Если вы запутались с объявлением массива как [], не будьте, потому что: Начиная с PHP 5.4 вы также можете использовать синтаксис короткого массива, который заменяет array() на []. И мой код делает то же самое, что и ваш рубин. Но об алгоритме вы правы, это еще не решение. – DevStan

+0

спасибо за разъяснение этого. Теперь я тестировал его с версией 5.4 и работал. теперь мне просто нужно немного подправить его –

+0

Это решение отлично работает только для однозначных последовательных номеров. Попробуйте со следующим массивом: $ a = [1, 2, 3, 6, 9, 10, 11, 12, 15]; В идеале он должен также возвращать 9,10,11,12, но он НЕ будет, тогда как он будет возвращать только 1,2,3, потому что это одиночные цифры. –

1

Вот питон (мой PHP не слишком хорошо), что делает то, что просит ваше описание в O (N), если ваша последовательность убывает:

lists = dict() 
for i in val: 
    if i in lists: 
     continue 
    a = {i} 
    if (i + 1) in lists: 
     b = lists[i+1] 
     b.update(a) 
     a = b 
    if (i - 1) in lists: 
     b = lists[i-1] 
     # this messes up the complexity 
     for k in b: 
      lists[k] = a 
     a.update(b) 
    lists[i] = a 

Идея заключается в том что lists поддерживает набор индексов на все элементы в списке. Всякий раз, когда вы сталкиваетесь с новым элементом, предыдущий и следующий наборы объединяются, если они присутствуют.

update операция является технически o(n), но это не усугубляется внешним контуром, так как может быть только n вставки в наборы путем слияния. В целом o(n)

Если последовательность не сортируется, слияние наборов +1 и -1 дает не очень хорошую сложность.

5

Это не O (п), но вы можете попробовать это:

// Define array 
$array = array(5,8,3,2,10,11,15,13,12,1,4,5,16); 

// Sorting 
asort($array); 

$previous = null; 
$result = array(); 
$consecutiveArray = array(); 

// Slice array by consecutive sequences 
foreach($array as $number) { 
    if ($number == $previous + 1) { 
     $consecutiveArray[] = $number; 
    } else { 
     $result[] = $consecutiveArray; 
     $consecutiveArray = array($number); 
    } 
    $previous = $number; 
} 
$result[] = $consecutiveArray; 

// Get length of each sub array 
$count = array_map('count', $result); 

Вы можете получить максимальную длину от max($count).

Это решение дает следующий массив:

array(
    0 => array(1,2,3,4,5) 
    1 => array(5) 
    2 => array(8) 
    3 => array(10,11,12,13) 
    4 => array(15,16) 
+0

что такое временная сложность? O (NlogN)? –

+0

Это зависит от функции сортировки. Если вы предоставили отсортированный массив, вы можете опустить сортировку и получить O (n). – Brejk

+0

Функция сортировки должна быть в алгоритме. я бы сортировал его с помощью sort() или asort, если у него меньше времени. так что же сложность asort O (1)? –

Смежные вопросы