634 · 单词矩阵

634 · 单词矩阵

描述
给出一系列 不重复的单词,找出所有用这些单词能构成的 单词矩阵。
一个有效的单词矩阵是指, 如果从第 k 行读出来的单词和第 k 列读出来的单词相同(0 <= k < max(numRows, numColumns)),那么就是一个单词矩阵.
例如,单词序列为 [“ball”,“area”,“lead”,“lady”] ,构成一个单词矩阵。因为对于每一行和每一列,读出来的单词都是相同的。

b a l l
a r e a
l e a d
l a d y
现在至少有一个单词并且不多于1000个单词
所有的单词都有相同的长度
单词的长度最短为 1 最长为 5
每一个单词均由小写字母组成

样例
样例 1:

输入:
[“area”,“lead”,“wall”,“lady”,“ball”]
输出:
[[“wall”,“area”,“lead”,“lady”],[“ball”,“area”,“lead”,“lady”]]

解释:
输出包含 两个单词矩阵,这两个矩阵的输出的顺序没有影响(只要求矩阵内部有序)。
样例 2:

输入:
[“abat”,“baba”,“atan”,“atal”]
输出:
[[“baba”,“abat”,“baba”,“atan”],[“baba”,“abat”,“baba”,“atal”]]

public class Solution {
    /**
     * @param words: a set of words without duplicates
     * @return: all word squares
     */
     int wordlen ;
     HashMap<String , List<String>> prefix  = new HashMap<>();
     List<String> str = new ArrayList<>() ;
     List<List<String>> ans = new ArrayList<>() ;
    public List<List<String>> wordSquares(String[] words) {
        // write your code here
        if(words == null ||words.length == 0){
            return ans ;
        }
        initPrefix(words) ;
        wordlen = words[0].length() ;
        dfs(0) ;
        return ans ;
    }
    public void initPrefix(String[] words){
        for(int i = 0 ; i < words.length ; i++){
            String item = words[i] ;
            if(! prefix.containsKey("")){
                prefix.put("" , new ArrayList<String>()) ;
            }
            prefix.get("").add(item) ;
            for(int j = 0 ; j < item.length() ; j++){
                if(! prefix.containsKey(item.substring(0 , j+1))){
                    prefix.put(item.substring(0 , j+1) ,new ArrayList<String>()) ;
                }
                prefix.get(item.substring(0 , j+1)).add(item) ;
            }
        }
    }
    public void dfs(int len){
        if(len == wordlen){
            ans.add(new ArrayList<>(str)) ;
            return  ;
        }
        String pre = "" ;
        for(int i = 0 ; i < len ; i++){
            pre += str.get(i).charAt(len) ;
        }
        List<String> w = prefix.get(pre) ;
        for(int i = 0 ; i < w.size() ; i++){
            if(! checkPrefix(len , w.get(i))){
                continue ;
            }
            str.add(w.get(i)) ;
            dfs(len + 1) ;
            str.remove(str.size()-1) ;
        }
    }
    public boolean checkPrefix(int l , String nextWord){
        for(int j = l + 1 ; j < wordlen ; j++){
            String pre = "" ;
            for(int k = 0 ; k < l ; k++){
                pre = pre + str.get(k).charAt(j);
            }
            pre += nextWord.charAt(j) ;
            if(! prefix.containsKey(pre)){
                return false ;
            }
        }
        return true ;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值