活跃农民
- 积分
- 512
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2019-9-30
- 最后登录
- 1970-1-1
|
本帖最后由 我已全仓 于 2022-3-2 23:49 编辑
二分长度 然后滚动hash 时间复杂度O(nlogn) 感觉应该是这样的
大致写了下,能过样例了。我这里偷懒用了stringbuilder,理论上要换成滚动hash也就是Rabin-Karp法就是真正的O(nlogn)了- // "static void main" must be defined in a public class.
- public class Main {
- public static void main(String[] args) {
- var tmp = findLongestPatternAndTime(", hey guys, hey Hannah, hey 1");
- System.out.println("pattern = \'" + tmp[0] + "\' , times = " + tmp[1]);
- }
- static String pattern;
- static int times;
- private static String[] findLongestPatternAndTime(String s) {
- pattern = "";
- int left = 0, right = s.length() / 2;
- while (left <= right) {
- int mid = left + (right - left) / 2;
- if (valid(s, mid)) {
- left = mid + 1;
- } else {
- right = mid - 1;
- }
- }
- return new String[] {pattern, String.valueOf(times)};
- }
-
- // varify whether exist a pattern, of which length is len
- private static boolean valid(String s, int len) {
- var strToPos = new HashMap<String, List<Integer>> ();
- var sb = new StringBuilder(s.substring(0, len));
- boolean found = false;
- for (int i = 0; i < s.length() - len; ++i) {
- var p = sb.toString();
- strToPos.computeIfAbsent(p, x -> new ArrayList<> ());
- var list = strToPos.get(p);
- if (list.isEmpty() || i - list.get(list.size() - 1) >= len) {
- list.add(i);
- }
- if (list.size() > 1) {
- pattern = p;
- times = list.size();
- found = true;
- }
- sb.delete(0, 1);
- sb.append(s.charAt(i + len));
- }
- return found;
- }
- }
复制代码 |
|