2016-01-14 3 views
2

Я пытаюсь ответить на следующий вопрос: учитывая отсортированный массив с некоторыми упорядоченными числами и некоторыми непересекающимися числами, напишите алгоритм, который получает пару {start, end} для каждой группы последовательных номера. У последовательных номеров есть разница только 1.Массив с последовательными номерами - Алгоритм

До сих пор я могу думать только грубой силы метод:

public static void main(String[] args) { 
    int[] array = { 4, 5, 6, 7, 8, 9, 12, 15, 16, 17, 18, 20, 22, 23, 24, 27 }; 
    Map<Integer, Integer> list = new HashMap<Integer, Integer>(); 

    list = findIndex(array); 
} 

// Bruteforce 
private static Map<Integer, Integer> findIndex(int[] array) { 
    Map<Integer, Integer> list = new HashMap<Integer, Integer>(); 

    int x = -1, y = -1; 

    int end = array.length; 
    for (int i = 0; i < end; i++) { 
     x = i; 
     while (i < end - 1) { 

      if (array[i] + 1 == array[i + 1]) { 
       i++; 
       y = i; 
      } else { 
       if (x != y && x >= 0) { 
        list.put(x, y); 
        System.out.println("i = " + x + " to j = " + y); 
        i = i + 1; 
        break; 
       } 
      } 
     } 

    } 
    return list; 
} 

Выход:

i = 0 to j = 5 
i = 7 to j = 10 
i = 12 to j = 14 

Он отлично работает, но как я могу улучшить временную сложность?

+0

проблема с вашим кодом - это не столько алгоритмическая сложность, сколько ясность. Этот код на самом деле повторяет только один раз через массив, хотя вложенный цикл скрывает это. O (n) - лучшее, что вы можете сделать. –

+0

@AndrewPalmer Cant мы используем двоичный поиск здесь? – Sarah

+0

Я должен сказать, что это действительно интересная мысль. Это определенно не будет стандартным приложением двоичного поиска, но в зависимости от того, что гарантировано в отношении массива, вы можете определить, есть ли 8 пробелов и начать сужаться там, где есть пробелы. –

ответ

1

Вам не нужно гнездо петли для этого:

int end = array.length; 
if (end > 0) { 
    int start = 0; 
    for (int i = 1; i < end; i++) { 
     if (array[i] != array[i - 1] + 1) { 
      if (i - start > 1) { 
       list.put(start, i - 1); 
       System.out.println("i = " + start + " to j = " + (i - 1)); 
      } 
      start = i; 
     } 
    } 
    if (end - start > 1) { 
     list.put(start, end - 1); 
     System.out.println("i = " + start + " to j = " + (end - 1)); 
    } 
} 
0

Как только отсортированный начальный массив, вы можете иметь O (N) реализацию этого алгоритма, как это:

private static Map<Integer, Integer> getConsecutive(final int[] array) { 
    final Map<Integer, Integer> list = new TreeMap<Integer, Integer>(); 
    int startIndex = 0; 
    int endIndex = 0; 
    for (int i = 1; i < array.length; i++) { 
     if (array[i - 1] + 1 == array[i]) 
      endIndex = i; 
     else { 
      if (endIndex > startIndex) 
       list.put(startIndex, endIndex); 
      startIndex = endIndex = i; 
     } 
    } 
    if (endIndex > startIndex) 
     list.put(startIndex, endIndex); 
    return list; 
} 
+1

Это не приведет к тем же результатам, что и код в вопросе. Во-первых, он не будет игнорировать изолированные номера, такие как 12, 20 и 27 в примере ввода. –

+1

@JohnSensebe будет игнорировать их –

+0

Можем ли мы сделать это с помощью двоичного поиска? – Sarah

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