Ваш подход не плох с точки зрения производительности. Запись всего в одном утверждении не обязательно является улучшением. Более плотный исходный код не означает лучшую производительность.
Одна вещь, которую вы должны улучшить, - это не подсчитывать все вхождения, когда вы хотите знать только, есть ли вхождения. Использование anyMatch
выражает намерение и будет более эффективным, так как anyMatch
может остановить поиск, как только будет найдено совпадение:
public String checkIfStringsHaveSubStrings(String s1, String s2) {
boolean[] alphabets = new boolean['z' - 'a' + 1];
s1.chars().forEach(s -> alphabets[s - 'a'] = true);
return s2.chars().anyMatch(s -> alphabets[s - 'a'])? "YES": "NO";
}
Временный массив boolean[]
с 26 элементами ничего не значит беспокоиться, но если вы настаиваете на сокращении потребления памяти, 26 значений истинности можно выразить как 26 битов, которые вписываются в одно значение int
.
public String checkIfStringsHaveSubStrings(String s1, String s2) {
int alphabets = s1.chars().map(c -> 1 << c - 'a').reduce(0, (a,b) -> a | b);
return s2.chars().map(c -> 1 << c - 'a').anyMatch(i -> (i & alphabets) != 0)?"YES":"NO";
}
Если вы хотите express, это в качестве одного оператора любой ценой вы можете использовать
public String checkIfStringsHaveSubStrings(String s1, String s2) {
return (s1.chars().map(c -> 1 << c - 'a').reduce(0, (a,b) -> a | b)
& s2.chars().map(c -> 1 << c - 'a').reduce(0, (a,b) -> a | b)) != 0? "YES": "NO";
}
Но должно быть очевидно, что теперь, когда он обрабатывает всю вторую строку, а не останавливается при первом совпадении, он менее эффективен.