Как определить, есть ли в целочисленном массиве повторяющиеся элементы или нет?

#java

Вопрос:

Меня попросили написать код, который указывает, есть ли в целочисленном массиве повторяющиеся элементы или нет. Это то, что у меня есть до сих пор:

 int[] input = {1, 2, 3, 4, 1}; boolean hasDuplicates = false;  for (int i = 0; i lt; input.length; i  ) {  for (int j = i   1; j lt; input.length; j  ) {  if (input[i] != input[j]) {  hasDuplicates = false;  } else if (input[i] == input[j]) {  hasDuplicates = true;  }  } }  

Однако этот код работает не так, как предполагалось, потому hasDuplicates что он всегда false работает .

Комментарии:

1. потому что вы должны вернуться, как только определите, что в списке есть дубликаты. вы, по сути, перезаписываете свои предыдущие результаты на каждой итерации

2. Если вы проследите шаги в своем коде вручную, вы увидите, где вы ошиблись.

Ответ №1:

Как только вы решите , что массив hasDuplicates , вы никогда не сможете его изменить; вы не сможете заставить исчезнуть дубликат после. Также используйте break цикл, в данный момент hasDuplicates становится правдой

 int[] input = {1, 2, 3, 4, 1}; boolean hasDuplicates = false;  for (int i = 0; i lt; input.length; i  ) {  for (int j = i   1; j lt; input.length; j  ) {  if (input[i] == input[j]) {  hasDuplicates = true;  break;  }  }  if (hasDuplicates)  break; }  

Еще проще в методе, непосредственно использовать return

 static boolean hasDup(int[] input) {  for (int i = 0; i lt; input.length; i  )  for (int j = i   1; j lt; input.length; j  )  if (input[i] == input[j])   return true;  return false; }  

Ответ №2:

Вы также можете выполнить итерацию по массиву один раз, если используете хэш-набор. Если add() возвращает false, то мы знаем, что видели это число раньше.

 int[] input = {1, 2, 3, 4, 1}; boolean hasDuplicates = false; HashSetlt;Integergt; duplicateSet = new HashSetlt;gt;();  for (int i = 0; i lt; input.length; i  ) {  if(!duplicateSet.add(Integer.valueOf(input[i])))  {  hasDuplicates = true;  break;  } }  return hasDuplicates;  

Комментарии:

1. new Integer() может создать ненужные накладные расходы. Используйте Integer.valueOf() вместо этого или, еще лучше, автобоксы.

Ответ №3:

Вы также можете воспользоваться преимуществами заданной структуры данных:

 int[] input = {1, 2, 3, 4, 1}; boolean hasDuplicates = false;   Setlt;Integergt; set = new HashSetlt;gt;(input.length);  for (int i : input) {  if (set.add(i)) {  hasDuplicates = false;  }  else {  hasDuplicates = true;  break;  } }  

add(E e) Set возвращает значение true, если этот набор еще не содержал указанный элемент.

Вкратце:

 int[] input = {1, 2, 3, 4, 1}; boolean hasDuplicates = false;   Setlt;Integergt; set = new HashSetlt;gt;(input.length);  for (int i : input) {  if (!set.add(i)) {  hasDuplicates = true;  break;  } }  

Ответ №4:

Java 8 облегчает жизнь. вот, пожалуйста

 int[] input = {1, 2, 3, 4, 1};  boolean hasDuplicates = false;  if(Arrays.stream(input).distinct().count() != input.length)  hasDuplicates=true;  System.out.println(hasDuplicates);  

Комментарии:

1. Это красиво, лаконично и читабельно. Однако, если входные данные содержат миллион элементов, а первые два являются дубликатами, другие ответы немедленно вернут значение true. Ваш по-прежнему будет просматривать оставшиеся 999 998 элементов, прежде чем вернется значение true.

Ответ №5:

Используя потоки Java 8, останавливаясь на первом найденном дубликате, однострочном:

 int[] input = {1, 2, 3, 4, 1}; boolean hasDuplicates = !(Arrays.stream(input).allMatch(new HashSetlt;gt;()::add))