1. 程式人生 > >LeetCode-652. Find Duplicate Subtrees

LeetCode-652. Find Duplicate Subtrees

Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node of any one of them.

Two trees are duplicate if they have the same structure with same node values.

Example 1:

        1
       / \
      2   3
     /   / \
    4   2   4
       /
      4

The following are two duplicate subtrees:

      2
     /
    4

and

    4

Therefore, you need to return above trees' root in the form of a list.

題解:

本來用set<TreeNode*>發現沒法去重,然後構造了一個JudgeNode結構體

然後。。

第一次ac結果。。448ms

class Solution {
public:
  struct JudgeNode {
    TreeNode* t;
    string s;
  };
  vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
      vector<TreeNode*> ans;
    if (root == NULL) {
      return ans;
    }
    vector<TreeNode*> subtree;
    map<string, TreeNode*> mp;
    getAllSubtrees(root, subtree);
    int n = subtree.size();
    vector<JudgeNode*> tmp;
    for (int i = 0; i < n; i++) {
      JudgeNode* j = new JudgeNode();
      j->t = subtree[i];
      j->s = getString(subtree[i]);
      tmp.push_back(j);
    }
    for (int i = 0; i < n - 1; i++) {
      for (int j = i + 1; j < n; j++) {
        if (tmp[i]->s == tmp[j]->s) {
          mp.insert(pair<string, TreeNode*>(tmp[i]->s, tmp[i]->t));
        }
      }
    }
    map<string, TreeNode*>::iterator it;
    for (it = mp.begin(); it != mp.end(); it++) {
      ans.push_back(it->second);
    }
    return ans;
  }
  static string getString (TreeNode* a) {
    string res;
    queue<TreeNode*> bfs;
    bfs.push(a);
    res+=a->val;
    while (bfs.empty() == false) {
      TreeNode* node = bfs.front();
      bfs.pop();
      if (node->left != NULL) {
        bfs.push(node->left);
        res += to_string(node->left->val);    
      }
      else {
        res += 'x';
      }
      if (node->right != NULL) {
        bfs.push(node->right);
        res += to_string(node->right->val);  
      }
      else {
        res += 'x';
      }
    }
    return res;
  }
  static void getAllSubtrees(TreeNode* root, vector<TreeNode*> &subtree) {
    queue<TreeNode*> bfs;
    bfs.push(root);
    while (bfs.empty() == false) {
      TreeNode* node = bfs.front();
      subtree.push_back(node);
      bfs.pop();
      if (node->left != NULL) {
        bfs.push(node->left);
      }
      if (node->right != NULL) {
        bfs.push(node->right);
      }
    }
  }
};

還是低效率的解法。。。我的思路就是這樣了。。能優化的都儘可能優化了還是168ms。。。

class Solution {
public:
  vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
    vector<TreeNode*> subtree;
    if (root == NULL) {
      return subtree;
    }
    map<string, vector<TreeNode*>> mp;
    getAllSubtrees(root, subtree);
    int n = subtree.size();
    for (int i = 0; i < n; i++) {
      string s = getString(subtree[i]);
      if (mp.find(s) != mp.end()) {
        mp[s].push_back(subtree[i]);
      }
      else {
        mp.insert(pair<string, vector<TreeNode*>>(s, vector<TreeNode*>(1, subtree[i])));
      }
    }
    subtree.clear();
    map<string, vector<TreeNode*>>::iterator it;
    for (it = mp.begin(); it != mp.end(); it++) {
      if (it->second.size() > 1) {
        subtree.push_back(it->second[0]);
      }
    }
    return subtree;
  }
  static string getString (TreeNode* a) {
    string res;
    queue<TreeNode*> bfs;
    bfs.push(a);
    res += a->val;
    while (bfs.empty() == false) {
      TreeNode* node = bfs.front();
      bfs.pop();
      if (node->left != NULL) {
        bfs.push(node->left);
        res += to_string(node->left->val);
      }
      else {
        res += 'x';
      }
      if (node->right != NULL) {
        bfs.push(node->right);
        res += to_string(node->right->val);
      }
      else {
        res += 'x';
      }
    }
    return res;
  }
  static void getAllSubtrees(TreeNode* root, vector<TreeNode*> &subtree) {
    queue<TreeNode*> bfs;
    bfs.push(root);
    while (bfs.empty() == false) {
      TreeNode* node = bfs.front();
      subtree.push_back(node);
      bfs.pop();
      if (node->left != NULL) {
        bfs.push(node->left);
      }
      if (node->right != NULL) {
        bfs.push(node->right);
      }
    }
  }
};