0

I'm solving problem336 in Leetcode, while I found the highest upvoted answer here used Trie structure in java. So, I wrote it in C++ again. I tried to optimize, but the Runtime and Memory are still very bad. Initially, I used shared_ptr, then the runtime: ~800 ms, memory: 400Mb. Then, I used new pointer, it became ~300ms, 200Mb. Still much slower than Java (20ms, 50Mb). I tried several times, but it's still 10x slower. My code structure and logic is just the same with the java implemented code, but it's so slow. I cannot figure out why! here is my code:

struct TrieNode {
    TrieNode *next[26];
    int index = -1;
    vector<int> list;
    TrieNode(){
        memset(next,NULL,sizeof(next));
    }
    ~TrieNode() {
        for (int i = 0; i < 26; ++i) {
            if (next[i]) delete(next[i]);
        }
    }
};

bool isPalindrome(const string &word, int start, int end) {
    while (start < end) {
        if (word[start] != word[end])
            return false;
        ++start;
        --end;
    }
    return true;
}

int addword(TrieNode* root, const string &word, int index) {
    for (int i = word.size() - 1; i >= 0; --i) {
        int j = word[i] - 'a';
        if (!(root->next[j])) {
            root->next[j] = new TrieNode;
        }
        if (isPalindrome(word, 0, i))
            root->list.push_back(index);
        root = root->next[j];
    }
    root->index = index;
    root->list.push_back(index);
    return 0;
}

void search(TrieNode* root, vector<string> &words, int index, vector<vector<int>> &res) {
    for (int i = 0; i < words[index].size(); ++i) {
        if (root->index >= 0 && root->index != index && isPalindrome(words[index], i, words[index].size() - 1)) {
            res.push_back({index, root->index});
        }
        root = root->next[words[index][i] - 'a'];
        if (!root) return;
    }
    for (int i : root->list) {
        if (i == index) continue;
        res.push_back({index, i});
    }
}

vector<vector<int>> palindromePairs(vector<string>& words) {
    vector<vector<int>> res;
    TrieNode *root = new TrieNode;
    for (int i = 0; i < words.size(); ++i) {
        addword(root, words[i], i);
    }
    for (int i = 0; i < words.size(); ++i) {
        search(root, words, i, res);
    }
    delete root;
    return res;
}
SRIDHARAN
  • 1,196
  • 1
  • 15
  • 35
  • 1
    Does this answer your question? [C++ performance vs. Java/C#](https://stackoverflow.com/questions/145110/c-performance-vs-java-c) – Aniket Sahrawat May 06 '20 at 04:57
  • 1
    Java calls `delete` never in such simple application. – 273K May 06 '20 at 05:01
  • How are you timing it? Taking leetcode’s timings? They’re very unreliable and have always been. Even running the same code several times can get wildly different results. So you’d need to set up a proper benchmark first. – Sami Kuhmonen May 06 '20 at 05:09
  • 1
    There are tools called profilers that can help you understand where the time is going. – Marc Glisse May 06 '20 at 05:13
  • 1
    One possible suspect: `vector list;`. From Java 8, `new ArrayList<>()` doesn't allocate the backing are - it is only allocated on the first `add()` call – Thomas Kläger May 06 '20 at 06:20
  • 1
    Which compile command do you use, and does it contain -O3? – JVApen May 06 '20 at 06:33
  • 1
    You don't need the `if` test in the destructor. `delete` already tests that. Don't test it again. – user207421 May 06 '20 at 07:00

0 Answers0