|
| 1 | +impl Solution { |
| 2 | + pub fn longest_dup_substring(s: String) -> String { |
| 3 | + let a = s.as_bytes(); |
| 4 | + let n = a.len(); |
| 5 | + let mut sa: Vec<i32> = Vec::with_capacity(n); |
| 6 | + let mut r: Vec<i32> = a.iter().map(|c| *c as i32).collect(); |
| 7 | + let mut m = 128; |
| 8 | + let mut h = vec![0; n.max(m)]; |
| 9 | + let mut x: Vec<i32> = Vec::with_capacity(n); |
| 10 | + unsafe { sa.set_len(n); x.set_len(n); } |
| 11 | + for i in 0..n { h[r[i] as usize] += 1; } |
| 12 | + for i in 1..m { h[i] += h[i-1]; } |
| 13 | + for i in (0..n).rev() { let v = &mut h[r[i] as usize]; *v -= 1; sa[*v as usize] = i as i32; } |
| 14 | + let mut k: usize = 1; |
| 15 | + loop { |
| 16 | + for i in 0..k { x[i as usize] = (n-k+i) as i32; } |
| 17 | + let mut j = k; |
| 18 | + for i in 0..n { if sa[i] >= k as i32 { x[j] = sa[i]-k as i32; j += 1; } } |
| 19 | + for i in 0..m { h[i] = 0; } // h[0..m].fill(0); |
| 20 | + for &i in x.iter() { h[r[i as usize] as usize] += 1; } |
| 21 | + for i in 1..m { h[i] += h[i-1]; } |
| 22 | + for &i in x.iter().rev() { let v = &mut h[r[i as usize] as usize]; *v -= 1; sa[*v as usize] = i; } |
| 23 | + for i in 0..m { h[i] = 0; } // h[0..m].fill(0); |
| 24 | + m = 1; |
| 25 | + h[sa[0] as usize] = 0; |
| 26 | + for i in 1..n { |
| 27 | + if r[sa[i] as usize] != r[sa[i-1] as usize] || sa[i].max(sa[i-1]) >= (n-k) as i32 || r[sa[i] as usize+k] != r[sa[i-1] as usize+k] { m += 1; } |
| 28 | + h[sa[i] as usize] = m as i32-1; |
| 29 | + } |
| 30 | + for i in 0..n { r[i] = h[i]; } |
| 31 | + if m == n { break; } |
| 32 | + k *= 2; |
| 33 | + } |
| 34 | + k = 0; |
| 35 | + h[0] = 0; |
| 36 | + let mut res0 = 0; |
| 37 | + let mut res1 = 0; |
| 38 | + for i in 0..n { |
| 39 | + if r[i] > 0 { |
| 40 | + let j = sa[r[i] as usize-1] as usize; |
| 41 | + while i.max(j)+k < n && a[i+k] == a[j+k] { k += 1; } |
| 42 | + h[r[i] as usize] = k as i32; |
| 43 | + if k > res1 { |
| 44 | + res0 = i; |
| 45 | + res1 = k; |
| 46 | + } |
| 47 | + if k > 0 { k -= 1; } |
| 48 | + } |
| 49 | + } |
| 50 | + s[res0..res0+res1].to_string() |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +/// suffix automaton |
| 55 | +impl Solution { |
| 56 | + pub fn longest_dup_substring(s: String) -> String { |
| 57 | + const AB: usize = 26; |
| 58 | + #[derive(Clone, Default)] |
| 59 | + struct Node { f: i32, c: [i32; AB], num: u8, l: i32, lc: i32 } |
| 60 | + fn add(ch: usize, pool: &mut [Node], tail: &mut usize, allo: &mut usize) { |
| 61 | + let x = *allo; *allo += 1; |
| 62 | + pool[x].l = pool[*tail].l+1; |
| 63 | + let mut p = *tail; *tail = x; |
| 64 | + while pool[p].c[ch] == 0 { |
| 65 | + pool[p].c[ch] = x as i32; |
| 66 | + if p == 0 { pool[x].f = 0; return; } |
| 67 | + p = pool[p].f as usize; |
| 68 | + } |
| 69 | + let q = pool[p].c[ch] as usize; |
| 70 | + if pool[p].l+1 == pool[q].l { |
| 71 | + pool[x].f = q as i32; |
| 72 | + } else { |
| 73 | + let r = *allo; *allo += 1; |
| 74 | + pool[r] = Node { f: pool[q].f, c: pool[q].c, l: pool[p].l+1, ..Default::default() }; |
| 75 | + pool[x].f = r as i32; |
| 76 | + pool[q].f = r as i32; |
| 77 | + while pool[p].c[ch] == q as i32 { |
| 78 | + pool[p].c[ch] = r as i32; |
| 79 | + if p == 0 { break; } |
| 80 | + p = pool[p].f as usize; |
| 81 | + } |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + let s1 = s.as_bytes(); |
| 86 | + let n = s1.len(); |
| 87 | + let mut pool: Vec<Node> = vec![Default::default(); 2*n]; |
| 88 | + let mut tail = 0; let mut allo = 1; |
| 89 | + for &ch in s1.iter() { |
| 90 | + add((ch-b'a') as usize, &mut pool[..], &mut tail, &mut allo); |
| 91 | + pool[tail].num = 1; |
| 92 | + } |
| 93 | + |
| 94 | + let mut c = vec![0; n+1]; |
| 95 | + let mut seq = vec![0; allo]; |
| 96 | + for i in 0..allo { c[pool[i].l as usize] += 1; } |
| 97 | + for i in 1..=n { c[i] += c[i-1]; } |
| 98 | + for i in (0..allo).rev() { let r = &mut c[pool[i].l as usize]; *r -= 1; seq[*r] = i; } |
| 99 | + let mut res0 = 0; |
| 100 | + let mut res1 = 0; |
| 101 | + for i in (0..allo).rev() { |
| 102 | + let x = seq[i]; |
| 103 | + let p = pool[x].f as usize; |
| 104 | + if p > 0 { |
| 105 | + pool[p].num = (pool[p].num+pool[x].num).min(2); |
| 106 | + } |
| 107 | + let mut lc = -1; // maxContext |
| 108 | + for ch in 0..AB { |
| 109 | + if pool[x].c[ch] > 0 { |
| 110 | + lc = lc.max(pool[pool[x].c[ch] as usize].lc); |
| 111 | + } |
| 112 | + } |
| 113 | + pool[x].lc = lc+1; |
| 114 | + if pool[x].num > 1 && pool[x].l as usize > res1 { |
| 115 | + res0 = n-pool[x].lc as usize; |
| 116 | + res1 = pool[x].l as usize; |
| 117 | + } |
| 118 | + } |
| 119 | + s[res0-res1..res0].to_string() |
| 120 | + } |
| 121 | +} |
0 commit comments