Leetcode每日一题练习 ------ 3043. 最长公共前缀的长度

Leetcode 每日一题练习继续讨论:

3043. 最长公共前缀的长度
3043. Find the Length of the Longest Common Prefix

题解

题目中的数组要求求最长公共前缀,考虑到每个数组中的不同数字之间也可能存在公共前缀,为了避免对字符串进行重复遍历,可以使用字典树。字典树充分利用了数字每一位的信息,非常适用于类似本题目的求前缀等场景下,还有一道经典题目是求数组中任意两个数字的最大异或和,也可以使用字典树求解,利用异或运算异或两次后会回到数字本身的特性,用数字的二进制形式构造字典树,充分利用每个二进制位的信息,通过贪心尽量将每一位置为1,最终找到最大异或和,可参考P4551 最长异或路径

本题在对两个数组构建好两棵字典树后,对字典树同时进行dfs,依次选取每一层中相同的字符对应的子节点进行遍历,直到在某一层无法找到共同字符为止。用一个变量保存遍历到的树的最大深度即为最长公共前缀的长度。

代码

#pragma GCC optimize("O3", "unroll-loops")

const int TREESIZE = 10;

struct TrieNode{
    TrieNode *children[TREESIZE];
    bool isEndOfWord;

    TrieNode(): isEndOfWord(false){
        for (int i = 0;i<TREESIZE;++i){
            children[i] = nullptr;
        }
    }
};

class Trie{
    public:
    TrieNode *root;
    Trie(){root = new TrieNode();}

    void insert(const string& word){
        TrieNode* node = root;
        for(char c : word){
            if (node->children[c-'0'] == nullptr){
                node->children[c-'0'] = new TrieNode();
            }
            node = node->children[c-'0'];
        }
        node->isEndOfWord = true;
    }

    ~Trie() {
        function<void(TrieNode*)> deleteTrie = [&](TrieNode* node) {
            if(node == nullptr) return;
            for(int i = 0; i < TREESIZE; ++i){
                if(node->children[i] != nullptr){
                    deleteTrie(node->children[i]);
                }
            }
            delete node;
        };
        deleteTrie(root);
    };

};

class Solution {
public:
    int longestCommonPrefix(vector<int>& arr1, vector<int>& arr2) {
        ios::sync_with_stdio(false);
        Trie *trie1 = new Trie();
        for (int num : arr1){
            string numstr = to_string(num);
            trie1->insert(numstr);
        }
        Trie *trie2 = new Trie();
        for (int num : arr2){
            string numstr = to_string(num);
            trie2->insert(numstr);
        }
        int result = 0;
        dfs(trie1->root, trie2->root, 0, result);
        return result;
        
    }

    void dfs(TrieNode* root1,TrieNode* root2, int depth, int& result){
        result = max(result, depth);
        for(int i=0;i<TREESIZE;i++){
            if (root1->children[i] != nullptr && root2->children[i] != nullptr){
                cout<< i;
                dfs(root1->children[i],root2->children[i],depth+1,result);
            }
        }
    }
};
5 个赞

刷题佬!来了!

1 个赞

感谢你的分享!

1 个赞