Код для удаления повторяющихся символов в строке без использования дополнительного буфера. ПРИМЕЧАНИЕ. Одна или две дополнительные переменные являются точными.Дополнительный массив не является:
import java.util.*;
public class Main{
public static char[] removeDupes(char[] arr){
if (arr == null || arr.length < 2)
return arr;
int len = arr.length;
int tail = 1;
for(int x = 1; x < len; x++){
int y;
for(y = 0; y < tail; y++){
if (arr[x] == arr[y]) break;
}
if (y == tail){
arr[tail] = arr[x];
tail++;
}
}
return Arrays.copyOfRange(arr, 0, tail);
}
public static char[] bigArr(int len){
char[] arr = new char[len];
Random r = new Random();
String alphabet = "[email protected]#$%^&*()-=_+[]{}|;:',.<>/?`~";
for(int x = 0; x < len; x++){
arr[x] = alphabet.charAt(r.nextInt(alphabet.length()));
}
return arr;
}
public static void main(String args[]){
String result = new String(removeDupes(new char[]{'a', 'b', 'c', 'd', 'a'}));
assert "abcd".equals(result) : "abcda should return abcd but it returns: " + result;
result = new String(removeDupes(new char[]{'a', 'a', 'a', 'a'}));
assert "a".equals(result) : "aaaa should return a but it returns: " + result;
result = new String(removeDupes(new char[]{'a', 'b', 'c', 'a'}));
assert "abc".equals(result) : "abca should return abc but it returns: " + result;
result = new String(removeDupes(new char[]{'a', 'a', 'b', 'b'}));
assert "ab".equals(result) : "aabb should return ab but it returns: " + result;
result = new String(removeDupes(new char[]{'a'}));
assert "a".equals(result) : "a should return a but it returns: " + result;
result = new String(removeDupes(new char[]{'a', 'b', 'b', 'a'}));
assert "ab".equals(result) : "abba should return ab but it returns: " + result;
char[] arr = bigArr(5000000);
long startTime = System.nanoTime();
System.out.println("2: " + new String(removeDupes(arr)));
long endTime = System.nanoTime();
long duration = (endTime - startTime);
System.out.println("Program took: " + duration + " nanoseconds");
System.out.println("Program took: " + duration/1000000000 + " seconds");
}
}
Как читать и говорить о коде выше:
- Метод называется removeDupes принимает массив примитивных символов, называемых обрами.
- arr возвращается как массив примитивных символов «по значению». Принятый arr - мусор, собранный в конце метода участника Main's removeDupes.
- Сложность выполнения этого алгоритма - O (n) или, более конкретно, O (n + (малая константа)), константа - это уникальные символы во всем массиве примитивных символов.
- CopyOfRange не увеличивает значительную сложность выполнения, поскольку только копирует небольшое постоянное количество элементов. Массив char, называемый arr, не проходит полностью.
- Если вы передаете null в removeDupes, метод возвращает null.
- Если вы передадите пустой массив примитивных символов или массив, содержащий одно значение, возвращается немодифицированный массив.
- Метод removeDupes выполняется так же быстро, как это возможно физически, полностью используя кеш L1 и L2, поэтому Branch redirects are kept to a minimum.
- Негрубованный компьютер стандартной версии 2015 года должен иметь возможность завершить этот метод с помощью примитивного массива символов, содержащего 500 миллионов символов в диапазоне от 15 до 25 секунд.
Объясните, как этот код работает:
Первая часть массива, переданного в используется в качестве хранилища для уникальных персонажей, которые в конечном счете возвращены. В начале функции ответ: «символы от 0 до 1» от 0 до хвоста.
Мы определяем переменную y вне цикла, потому что мы хотим найти первое место, где индекс массива, который мы рассматриваем, был дублирован в нашем репозитории. Когда найден дубликат, он вырывается и завершается, хвост y == возвращает false, а репозиторий не предоставляется.
, когда индекс x, который мы просматриваем, не представлен в нашем репозитории, тогда мы вытаскиваем его и добавляем в конец нашего репозитория по хвосту индекса и хвосту инкремента.
В конце мы возвращаем массив между точками 0 и хвостом, который должен быть меньше или равен длине исходного массива.
Говоря точки упражнения для кодера интервью:
Будет ли программа ведет себя по-разному, если изменить у ++ в ++ у? Почему или почему нет.
Является ли массив копией в конце, представляет собой другой «N» проход через весь массив, создающий сложность выполнения O (n * n) вместо O (n)? Почему или почему нет.
Можете ли вы заменить двойные равные на сравнение примитивных символов с .equals? Почему или почему нет?
Можно ли изменить этот метод для замены «по ссылке» вместо «теперь по значению»? Почему или почему нет?
Можете ли вы повысить эффективность этого алгоритма, сортируя хранилище уникальных значений в начале 'arr'? В каких обстоятельствах это будет более эффективно?
Вы просто хотите 'коллапс' повторяющихся символов, или удалить дубликаты полностью. То есть, если «abba» приведет к «aba» или «ab»? –