1. 程式人生 > 其它 >字串雜湊 + 字首和 + 二分

字串雜湊 + 字首和 + 二分

// leetcode 1044
class
Solution { int p = 13331; int maxn = (int)3e4+5; long[] H = new long[maxn]; // 前i個字元的hashcode long[] P = new long[maxn]; // 次方陣列 public String longestDupSubstring(String s) { int n = s.length(); P[0] = 1; for (int i = 1; i <= n; i++) { H[i]
= H[i-1] * p + s.charAt(i-1); P[i] = P[i-1] * p; } String ans = ""; int left = 0, right = n; while (left < right) { // 尋找最後一個滿足check的len,保證最大 int mid = left + ((right - left + 1) >> 1); String tmp = check(s, mid);
if (tmp.length() != 0) { // 存在 left = mid; } else { right = mid - 1; } ans = tmp.length() > 0? tmp:ans; } String tmp = check(s, left); ans = tmp.length() > 0 && tmp.length() > ans.length()? tmp: ans;
return ans; } // 判斷某個長度的子串是否為重複子串 public String check(String s, int len) { int n = s.length(); Set<Long> set = new HashSet<>(); for (int i = 1; i + len - 1 <= n; i++) { int j = i + len - 1; long hash = H[j] - H[i-1] * P[j-i+1]; if (set.contains(hash)) return s.substring(i - 1, i + len - 1); set.add(hash); } return ""; } }

字串雜湊 + 字首和

/**
 * https://blog.csdn.net/SHU15121856/article/details/109553503
 * 字串Hash + 字首和
 * eg. abcde
 * H[4] = a * p^4 + b * p^3 + c * p^2 + d * p^1 + e * p^0
 * H[l:r] = H[r] - H[l] * P^(r-l+1) 
 */
class Solution {
    int P = 13331;  // P進位制,經驗值(131、13331)
    int maxn = (int) 1e5+5;
    int[] H = new int[maxn];    // H[i]表示前i個字元的雜湊值
    int[] p = new int[maxn];    // 次方陣列

    public List<String> findRepeatedDnaSequences(String s) {
        int n = s.length();
        List<String> resultList = new LinkedList<>();
        p[0] = 1;

        for (int i = 1; i <= n; i++) {
            H[i] = H[i-1] * P + s.charAt(i-1);
            p[i] = p[i-1] * P;
        }

        Map<Integer, Integer> map = new HashMap<>();    // key為子串的Hash值
        for (int i = 1; i + 10 -1 <= n; i++) {
            int j = i + 10 -1;
            int hash = H[j] - H[i-1] * p[j-i+1]; 
            int cnt = map.getOrDefault(hash, 0);
            if (cnt == 1) resultList.add(s.substring(i-1, i+10-1));
            map.put(hash, cnt+1);
        }

        return resultList;
    }
}

作者:Ryanjie

出處:http://www.cnblogs.com/ryanjan/

本文版權歸作者和部落格園所有,歡迎轉載。轉載請在留言板處留言給我,且在文章標明原文連結,謝謝!

如果您覺得本篇博文對您有所收穫,覺得我還算用心,請點選右下角的 [推薦],謝謝!