Если вам нужно поддерживать символы Юникода, которые не представлены суррогатными символами, это будет сделано:
private static boolean isUnique(String inputString) {
long[] used = new long[1024];
for (char c : inputString.toCharArray()) {
if ((used[c >>> 6] & (1 << c)) > 0) {
return false;
}
used[c >>> 6] |= 1 << c;
}
return true;
}
Он использует биты для экономии памяти. По сути, это то же самое, что если бы вы использовали массив логических значений:
private static boolean isUnique2(String inputString) {
boolean[] used = new boolean[65536];
for (char c : inputString.toCharArray()) {
if (used[c]) {
return false;
}
used[c] = true;
}
return true;
}
Если вам нужно только поддерживать символы ASCII, вы можете ограничить размер used
в любом случае, чтобы уменьшить требуемую память (например, long[4]
и boolean[256]
). Ниже определенной длины inputString
, вероятно, быстрее выполнить проверку n ^ 2, чем выделить для этого память. Так что в идеале вы делаете комбинацию из двух на основе длины.
Если вам нужно поддерживать все возможные символы Юникода, вам придется изменить это для поддержки суррогатных пар символов. Вы можете обнаружить их с помощью Character.isHighSurrogate(c)
. См. эту страницу для получения справки и поиска Google для получения более подробной информации.