2013-10-06 3 views
0

У меня есть отсортированный массив ArrayList целых чисел. Теперь у меня есть новое целое число для вставки в ArrayList. Это новое целое число должно быть вставлено в соответствующее положение, чтобы сохранить ArrayList в отсортированном порядке.Найти местоположение вставки

Я могу просто добавить целое число, а затем отсортировать его с помощью Collections.sort (ArrayList), но поскольку ArrayList слишком велик, этот вид занимает много времени, и мне нужно вставить много раз, поэтому я не хочу заканчивать сортировка несколько раз, что будет съедать мое время.

Collections.sort() имеет O (nlogn) (использует mergeSort).

Могу ли я иметь что-то меньшее, чем занятно, или я могу вручную найти позицию для вставки, которая занимает наименьшее время?

Время имеет высокий приоритет.

Заранее спасибо :)

ответ

1

Почему бы не просто идти по списку и добавить элемент в соответствующее положение. Поскольку ваш list уже отсортирован, новый list после insertion также будет sorted, и это будет операция O(N). Нет необходимости сортировать список снова и снова.

EDIT: - Теперь здесь есть две вещи. Один, если вам нужно найти местоположение элемента, в который он должен быть вставлен в текущий список, который вы можете сделать с помощью Binary Search. Фактически, вставка этого элемента в это место потребует всех элементов, которые следуют за ним, чтобы переместить одно пятно вперед, чтобы создать пространство для вставленного элемента, который, по моему мнению, еще эффективнее, чем вставка назад и сортировка снова.

+0

Я собирался предложить то же самое, на самом деле, но я не уверен если мы что-то неправильно читаем в вопросе ... – icedwater

+0

Спасибо. Это неплохая работа, которая составляет 170 секунд до 115, но мне нужно всего лишь 5 секунд. Так что все более эффективно. ?? – Sravan2023

+0

Вы можете найти место, где элемент должен быть вставлен с помощью 'двоичного поиска' в' O (log N) 'complex – Prateek

1

Возможно, вы захотите рассмотреть возможность использования другой структуры данных (например, TreeSet), так как вставка все равно приведет к смещению всех перемещаемых элементов. Вы можете использовать Collections.binarySearch, чтобы найти место для вставки, хотя, который возвращает:

Возвраты: Индекс ключа поиска, если он содержится в списке; в противном случае (- (точка ввода) - 1). Точка вставки определяется как точка, в которой ключ будет вставлен в список: индекс первого элемента больше ключа или list.size(), если все элементы в списке меньше указанного ключа. Обратите внимание, что это гарантирует, что возвращаемое значение будет> = 0 тогда и только тогда, когда ключ найден.

EDIT: Пример с TreeMap

TreeMap<Integer, Integer> numbers = new TreeMap<>(); 
private void add(int n) { 
    if(numbers.containsKey(n)) 
     numbers.put(n, numbers.get(n)+1); 
    else 
     numbers.put(n, 1); 
} 

private void remove(int n) { 
    if(numbers.containsKey(n)) { 
     int i = numbers.get(n); 
     if(i == 1) 
      numbers.remove(n); 
     else 
      numbers.put(n, i-1); 
    } 
} 

Пример с List

List<Integer> numbers = new ArrayList<>(); 
private void add(int n) { 
    int idx = Collections.binarySearch(numbers, n); 
    if(idx < 0) { 
     idx += 1; 
     idx *= -1; 
    } 
    numbers.add(idx, n); 
} 

private void remove(int n) { 
    numbers.remove(n); 
} 
+0

Элементы не уникальны, поэтому использование canse TreeSet – Sravan2023

+0

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

+0

Если элемент, который вы ищете, отсутствует в списке (так что элемент, который вы добавляете), он вернет '(- (точка ввода) - 1)'. Я все еще думаю, что вам нужна другая структура данных, возможно, вы можете использовать «TreeMap» и иметь значения в количестве вхождений элемента? – Alowaniak

0

Вы можете использовать свой собственный бинарный поиск, чтобы оценить позицию нового элемента, а затем вставить элемент в хорошем позиция

+0

Binary Search можно использовать для поиска существующего элемента в списке. Но здесь мне нужно найти место для вставки. Так как я могу реализовать двоичный поиск? – Sravan2023

+0

Если вы используете 'двоичный поиск', чтобы найти местоположение элемента, и если в списке нет этого элемента, двоичный поиск может вернуть последний индекс поиска - это будет оцененный индекс, в котором должен находиться ваш элемент. Затем вы должны использовать Inser Sort, чтобы поместить ваш элемент в нужное положение. ПРИМЕР: СПИСОК (1,2,3,4,6,7,8,9,10,11,12,13), и вы хотите поместить 5 в список Двоичный поиск вернет вам индекс около 3, затем вы можете проверить, если 'list.get (3)' больше или меньше вашего элемента и использовать сортировку вставки вправо/влево – Sylwek

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