【Leetcode】1065. Index Pairs of a String

題目地址:

https://leetcode.com/problems/index-pairs-of-a-string/

給定一個字符串ss,再給定一個字符串數組,如果數組中一個字符串是ss的子串,那麼就記下該子串在ss中的起始和結尾的下標(包括起始字符和結尾字符的下標)。返回所有這樣的下標。

思路是用Trie。先將數組中所有字符串存入一個Trie,然後從ss的每一個位置ii開始,在Trie中搜索是否存在s[i:]s[i:]的前綴,如果存在,則返回所有前綴的結尾下標。

import java.util.ArrayList;
import java.util.List;

public class Solution {
    
    class Trie {
        class Node {
            boolean isWord;
            Node[] next;
            
            Node() {
                next = new Node[26];
            }
        }
        
        private Node root;
        
        Trie(String[] words) {
            root = new Node();
            for (String word : words) {
                insert(word);
            }
        }
        
        private void insert(String word) {
            Node cur = root;
            for (int i = 0; i < word.length(); i++) {
                char c = word.charAt(i);
                if (cur.next[c - 'a'] == null) {
                    cur.next[c - 'a'] = new Node();
                }
                cur = cur.next[c - 'a'];
            }
            
            cur.isWord = true;
        }
        
        // 在Trie裏查找所有word[start:]的前綴,並把前綴的結尾字符的下標返回
        public List<Integer> hasPrefix(String word, int start) {
            List<Integer> end = new ArrayList<>();
            Node cur = root;
            for (int i = start; i < word.length(); i++) {
                char c = word.charAt(i);
                // 走到null的時候說明更長的前綴不可能再有了,退出循環
                if (cur.next[c - 'a'] == null) {
                   	break;
                }
                
                cur = cur.next[c - 'a'];
                // 找到一個前綴,就將其結尾下標加入list
                if (cur.isWord) {
                    end.add(i);
                }
            }
            
            return end;
        }
    }
    
    public int[][] indexPairs(String text, String[] words) {
        List<int[]> list = new ArrayList<>();
        Trie trie = new Trie(words);
        
        // 查找text[i:]在trie裏存在的所有前綴,並把區間端點加入list
        for (int i = 0; i < text.length(); i++) {
            for (int end : trie.hasPrefix(text, i)) {
                list.add(new int[]{i, end});
            }
        }
        
        // 轉爲數組返回
        int[][] res = new int[list.size()][];
        for (int i = 0; i < res.length; i++) {
            res[i] = list.get(i);
        }
        
        return res;
    }
}

時間複雜度O((n+m)l)O((n+m)l)nn爲text長度,mm爲words字符串個數,ll爲words裏最長字符串的長度。空間複雜度O((n+m)l)O((n+m)l)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章