算法——字符串搜索字典中匹配单词的所有位置

给定一个较长字符串big和一个包含较短字符串的数组smalls,设计一个方法,根据smalls中的每一个较短字符串,对big进行搜索。输出smalls中的字符串在big里出现的所有位置positions,其中positions[i]为smalls[i]出现的所有位置。
leetcode

字典树

解题思路:

  1. 先将用字典构造字典树。
  2. 然后依次截取所有下标开始的字符换,进行搜索。
  3. 搜索的时候,就检测当前节点是否为一个单词的结尾,如果是,就向答案中对应的单词列表添加当前的下标。
  4. 最后将列表转化为数组。
class Node {
    public Node[] next;
    public Boolean isEnd;
    public int id;
    public Node() {
        isEnd = false;
        next = new Node[26];
    }
}

class Solution {
    Node root = new Node();
    List<List<Integer>> res;
    public int[][] multiSearch(String big, String[] smalls) {
        res = new ArrayList<>();

        for(int i = 0; i < smalls.length; i++) {
            res.add(new ArrayList<>());
            build(smalls[i], i);
        }

        for(int i = 0; i < big.length(); i++) {
            search(big.substring(i, big.length()), i);
        }

        List<int[]> temp = new ArrayList<>();

        for(List<Integer> it : res) {
            int[] cur = new int[it.size()];
            for(int i = 0; i < it.size(); i++) cur[i] = it.get(i);
            temp.add(cur);
        }

        return temp.toArray(new int[temp.size()][]);       
    }

    private void build(String s, int i) {
        Node cur = root;
        for(char c : s.toCharArray()) {
            if(cur.next[c - 'a'] == null) {
                cur.next[c - 'a'] = new Node();
            }

            cur = cur.next[c - 'a'];
        }

        cur.isEnd = true;
        cur.id = i;
    }

    private void search(String word, int i) {
        Node cur = root;
        for(char c : word.toCharArray()) {
            if(cur.next[c - 'a'] == null) break;

            cur = cur.next[c - 'a'];
            if(cur.isEnd) {
                res.get(cur.id).add(i);
            }
        }
    }
}

暴力匹配

解题思路:

  1. 将单词放到一个哈希表中。
  2. 遍历字符串,截取所有可能的字符串进行匹配,并填入对应答案。
  3. 列表转化为数组。
class Solution {
    public int[][] multiSearch(String big, String[] smalls) {
        Map<String, Integer> map = new HashMap<>();
        List<List<Integer>> res = new ArrayList<>();
        int n = big.length();

        for(int i = 0; i < smalls.length; i++) {
            map.put(smalls[i], i);
        }  

        for(int i = 0; i < smalls.length; i++) {
            res.add(new ArrayList<>());
        }      

        for(int i = 1; i <= n; i++) {
            for(int j = 0; j < i; j++) {
                if(map.containsKey(big.substring(j, i))) {
                    res.get(map.get(big.substring(j, i))).add(j);
                }
            }
        }

        List<int[]> temp = new ArrayList<>();

        for(List<Integer> it : res) {
            int[] cur = new int[it.size()];
            for(int i = 0; i < it.size(); i++) cur[i] = it.get(i);
            temp.add(cur);
        }

        return temp.toArray(new int[temp.size()][]);
    }
}
posted @ 2020-11-25 16:51  lippon  阅读(272)  评论(0编辑  收藏  举报