LeetCode题解-02(树、字典树、堆)

目录

LeetCode题解

chap-4: 树#

1、验证二叉搜索树#

Copy
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: bool isValidBST(TreeNode* root) { if(root == nullptr) return true; if(root->left == nullptr && root->right == nullptr) return true; auto left = root->left, right = root->right; while(left){ if(left->val >= root->val) return false; left = left->right; } while(right){ if(right->val <= root->val) return false; right = right->left; } return isValidBST(root->left) && isValidBST(root->right); } };

2、恢复二叉搜索树#

思路:二叉搜索树满足中序遍历的有序性,可以通过查找中序遍历逆序对,进而确定交换值的位置

Copy
class Solution { public: TreeNode *pre = NULL, *first = NULL, *second = NULL; void recoverTree(TreeNode* root) { dfs(root); swap(first -> val, second -> val); } void dfs(TreeNode* root) { if (!root) return; dfs(root -> left); if (!pre) pre = root; if (root -> val < pre -> val) { if (!first) first = pre; second = root; } pre = root; dfs(root -> right); } };

Morris遍历

Copy
class Solution { public: void recoverTree(TreeNode* root) { TreeNode *first = NULL, *second, *prep = NULL; while (root) { if (!root->left) { if (prep && prep->val > root->val) { if (!first) first = prep, second = root; else second = root; } prep = root; root = root->right; } else { TreeNode *p = root->left; while (p->right && p->right != root) p = p->right; if (!p->right) { p->right = root; root = root->left; } else { p->right = NULL; if (prep && prep->val > root->val) { if (!first) first = prep, second = root; else second = root; } prep = root; root = root->right; } } } swap(first->val, second->val); } };

3、相同的树#

Copy
class Solution { public: bool isSameTree(TreeNode* p, TreeNode* q) { if(!p && !q) return true; if(!q || !p || p->val != q->val) return false; return isSameTree(p->left,q->left) && isSameTree(p->right,q->right); } };

4、对称二叉树#

Copy
class Solution { public: bool dfs(TreeNode* r,TreeNode* l){ if(!r && !l) return true; if(!r || !l || r->val != l->val) return false; return dfs(r->right,l->left) && dfs(r->left,l->right); } bool isSymmetric(TreeNode* root) { if(root == nullptr) return true; return dfs(root->right,root->left); } };

5、二叉树的层序遍历#

Copy
class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> ans; if(root == nullptr) return ans; queue<TreeNode*> q; q.push(root); while(q.size()){ int n = q.size(); vector<int> temp; while(n--){ auto t = q.front(); q.pop(); temp.push_back(t->val); if(t->left) q.push(t->left); if(t->right) q.push(t->right); } ans.push_back(temp); } return ans; } };

6、二叉树的层序遍历 II#

Copy
class Solution { public: vector<vector<int>> levelOrderBottom(TreeNode* root) { vector<vector<int>> res; queue<TreeNode*> q; if (root) q.push(root); while (q.size()) { vector<int> level; int len = q.size(); while (len -- ) { auto t = q.front(); q.pop(); level.push_back(t->val); if (t->left) q.push(t->left); if (t->right) q.push(t->right); } res.push_back(level); } reverse(res.begin(),res.end()); return res; } };

7、二叉树的锯齿形层序遍历#

Copy
class Solution { public: vector<vector<int>> zigzagLevelOrder(TreeNode* root) { vector<vector<int>> ans; if(root == nullptr) return ans; queue<TreeNode*> q; q.push(root); bool zig = false; while(q.size()){ int n = q.size(); vector<int> temp; while(n--){ auto t = q.front(); q.pop(); temp.push_back(t->val); if(t->left)q.push(t->left); if(t->right)q.push(t->right); } if(zig) reverse(temp.begin(),temp.end()); zig = !zig; ans.push_back(temp); } return ans; } };

8、二叉树的最大深度#

Copy
class Solution { public: int maxDepth(TreeNode* root) { if(root == nullptr) return 0; return max(maxDepth(root->left),maxDepth(root->right)) + 1; } };

9、从前序与中序遍历序列构造二叉树#

Copy
class Solution { public: unordered_map<int,int> pos; TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { int n = preorder.size(); for (int i = 0; i < n; i ++ ) pos[inorder[i]] = i; return dfs(preorder, inorder, 0, n - 1, 0, n - 1); } TreeNode* dfs(vector<int>&pre, vector<int>&in, int pl, int pr, int il, int ir) { if (pl > pr) return NULL; int k = pos[pre[pl]] - il; TreeNode* root = new TreeNode(pre[pl]); root->left = dfs(pre, in, pl + 1, pl + k, il, il + k - 1); root->right = dfs(pre, in, pl + k + 1, pr, il + k + 1, ir); return root; } };

10、从中序与后序遍历序列构造二叉树#

Copy
class Solution { public: TreeNode* buildTree(vector<int> in, vector<int> post) { if(in.size() == 0) return nullptr; auto root = new TreeNode(post.back()); int i = 0; while(i<in.size() && in[i] != post.back()) i++; root->left = buildTree(vector<int>(in.begin(),in.begin()+i),vector<int>(post.begin(),post.begin()+i)); root->right = buildTree(vector<int>(in.begin()+i+1,in.end()),vector<int>(post.begin()+i,post.end()-1)); return root; } };

11、将有序数组转换为二叉搜索树#

Copy
class Solution { public: TreeNode* sortedArrayToBST(vector<int> nums) { if(nums.empty()) return nullptr; int n = nums.size(), mid = n>>1; auto root = new TreeNode(nums[mid]); root->left = sortedArrayToBST(vector<int>(nums.begin(),nums.begin()+mid)); root->right = sortedArrayToBST(vector<int>(nums.begin()+mid+1,nums.end())); return root; } };

12、有序链表转换二叉搜索树#

Copy
class Solution { public: TreeNode* sortedListToBST(ListNode* head) { if(head == nullptr) return nullptr; auto dummy = new ListNode(-1); dummy->next = head; auto slow = dummy, fast = dummy; while(slow && fast){ slow = slow->next; if(fast->next) fast = fast->next->next; else fast = fast->next; } fast = dummy; while(fast->next != slow) fast = fast->next; auto root = new TreeNode(slow->val); fast->next = nullptr; root->left = sortedListToBST(dummy->next); root->right = sortedListToBST(slow->next); return root; } };

13、平衡二叉树#

Copy
class Solution { public: int maxdepth(TreeNode* root){ if(root == nullptr) return 0; return max(maxdepth(root->left),maxdepth(root->right)) + 1; } bool isBalanced(TreeNode* root) { if(root == nullptr) return true; if(abs(maxdepth(root->left) - maxdepth(root->right)) <= 1 && isBalanced(root->left) && isBalanced(root->right)) return true; else return false; } };

14、二叉树的最小深度#

Copy
class Solution { public: int minDepth(TreeNode* root) { if(root == nullptr) return 0; if(root->left == nullptr && root->right == nullptr) return 1; int l = INT_MAX, r = INT_MAX; if(root->left) l = min(minDepth(root->left),l); if(root->right) r = min(minDepth(root->right),r); return min(l,r)+1; } };

15、路径总和#

Copy
class Solution { public: bool hasPathSum(TreeNode* root, int targetSum) { if(root == nullptr) return false; if(root->left == nullptr && root->right == nullptr && targetSum == root->val) return true; return hasPathSum(root->left,targetSum - root->val) || hasPathSum(root->right, targetSum - root->val); } };

16、路径总和 II#

Copy
class Solution { public: vector<int> path; vector<vector<int>> ans; void dfs(TreeNode* root, int targetSum){ if(root == nullptr) return; if(root->left == nullptr && root->right == nullptr && root->val == targetSum) { path.push_back(root->val); ans.push_back(path); path.pop_back(); return; } path.push_back(root->val); dfs(root->left,targetSum - root->val); dfs(root->right,targetSum - root->val); path.pop_back(); } vector<vector<int>> pathSum(TreeNode* root, int targetSum) { dfs(root,targetSum); return ans; } };

17、二叉树展开为链表#

Copy
class Solution { public: void flatten(TreeNode* root) { if(root == nullptr) return; stack<TreeNode*>s; s.push(root); auto temp = new TreeNode(-1); while(s.size()){ auto t = s.top(); s.pop(); if(t->right) s.push(t->right); if(t->left) s.push(t->left); temp->left = nullptr; temp->right = t; temp = temp->right; } root = temp->right; } }; // O(1)空间负责度 class Solution { public: void flatten(TreeNode* root) { TreeNode *now = root; while (now) { if (now->left) { TreeNode *p = now->left; while (p->right) p = p->right; p->right = now->right; now->right = now->left; now->left = 0; } now = now->right; } } };

18、填充每个节点的下一个右侧节点指针【×】#

Copy
class Solution { public: Node* connect(Node* root) { if(root == NULL) return root; auto l = connect(root->left); auto r = connect(root->right); while(l && r){ l->next = r; l = l->right; r = r->left; } return root; } }; // 进阶 class Solution { public: Node* connect(Node* root) { if (!root) return root; auto source = root; while (root->left) { for (auto p = root; p; p = p->next) { p->left->next = p->right; if (p->next) p->right->next = p->next->left; } root = root->left; } return source; } };

19、填充每个节点的下一个右侧节点指针 II 【×】#

Copy
class Solution { public: Node* connect(Node* root) { if(!root) return root; auto cur = root; while(cur){ auto head = new Node(-1), tail = head; for(auto p =cur;p;p=p->next){ if(p->left) tail = tail->next = p->left; if(p->right) tail = tail->next = p->right; } cur = head->next; } return root; } };

20、二叉树中的最大路径和【×】#

Copy
class Solution { public: int ans = INT_MIN; int dfs(TreeNode* root){ if(!root) return 0; int l = max(0,dfs(root->left)); int r = max(0,dfs(root->right)); ans = max(ans,root->val + l + r); return root->val + max(l,r); } int maxPathSum(TreeNode* root) { dfs(root); return ans; } };

21、求根节点到叶节点数字之和#

Copy
class Solution { public: int ans = 0; int sumNumbers(TreeNode* root) { if(root)dfs(root, 0); return ans; } void dfs(TreeNode* root, int number) { number = number * 10 + root->val; if(!root -> left && !root->right) ans += number; if(root->left) dfs(root->left,number); if(root->right) dfs(root->right, number); } };

22、二叉树的前序遍历#

Copy
class Solution { public: vector<int> preorderTraversal(TreeNode* root) { vector<int> ans; if(root==nullptr) return ans; stack<TreeNode*> s; s.push(root); while(s.size()){ auto t = s.top(); s.pop(); ans.push_back(t->val); if(t->right) s.push(t->right); if(t->left) s.push(t->left); } return ans; } };

23、二叉树的后序遍历【×】#

Copy
class Solution { public: vector<int> postorderTraversal(TreeNode* root) { vector<int> ans; if(!root) return ans; stack<TreeNode*> s; s.push(root); while(s.size()){ root = s.top();s.pop(); ans.push_back(root->val); if(root->left) s.push(root->left); if(root->right) s.push(root->right); } reverse(ans.begin(),ans.end()); return ans; } }; // 不取巧 class Solution { public: vector<int> postorderTraversal(TreeNode* cur) { stack<TreeNode*> s; vector<int> ans; TreeNode* last = nullptr; // 开辟变量存储前一次访问位置 while(cur != nullptr || s.size()){ while(cur != nullptr){ s.push(cur); cur = cur->left; } cur = s.top(); if(cur->right == nullptr || cur->right == last){ ans.push_back(cur->val); last = cur; cur = nullptr; s.pop(); }else cur = cur->right; } return ans; } };

24、二叉搜索树迭代器#

Copy
class BSTIterator { public: stack<TreeNode*> s; BSTIterator(TreeNode* root) { while(root){ s.push(root); root = root->left; } } int next() { auto cur = s.top(); s.pop(); int v = cur->val; cur = cur->right; while(cur){s.push(cur); cur = cur->left;} return v; } bool hasNext() { return !s.empty(); } };

25、完全二叉树的节点个数#

1、对于每个节点,计算一直向左和一直向右的高度,如果相等则说明是满二叉树,那么该树节点个数为2h1

2、如果不相等则说明不是满二叉树,则需要递归地向下求解,该棵树的节点个数等于1+左子树节点数+右子树节点数

满完全二叉节点总数

Copy
class Solution { public: int countNodes(TreeNode* root) { if(!root) return 0; auto l = root, r = root; int a = 0, b = 0; while(l){a++; l = l->left;} while(r){b++; r = r->right;} if(a == b) return (1<<a) - 1; return countNodes(root->left) + countNodes(root->right) + 1; } };

26、翻转二叉树#

Copy
class Solution { public: TreeNode* invertTree(TreeNode* root) { if(root == nullptr) return root; swap(root->left, root->right); invertTree(root->left); invertTree(root->right); return root; } };

27、二叉搜索树中第K小的元素#

Copy
class Solution { public: int dfs(TreeNode* root){ if(!root) return 0; return dfs(root->left) + dfs(root->right) + 1; } int kthSmallest(TreeNode* root, int k) { int m = dfs(root->left); if(m+1 == k) return root->val; else if(m > k) return kthSmallest(root->left,k); else if(m == k){ root = root->left; while(root->right) root = root->right; return root->val; }else return kthSmallest(root->right,k-m-1); } };

28、二叉树的序列化与反序列化【×】#

Copy
class Codec { public: void dfs(TreeNode* root,string &help){ if(!root) help += "#,"; else{ help += to_string(root->val) + ','; dfs(root->left,help); dfs(root->right,help); } } // Encodes a tree to a single string. string serialize(TreeNode* root) { string help; dfs(root,help); return help; } TreeNode* vdfs(const string& data,int& i){ // 引用减少内存重复申请 + if(i>=data.size()) return NULL; int k = i; while(i<data.size() && data[i] != ',')i++; string s = data.substr(k,i++ - k); if(s == "#") return NULL; else{ auto t = new TreeNode(stoi(s)); t->left = vdfs(data,i); t->right = vdfs(data,i); return t; } } // Decodes your encoded data to tree. TreeNode* deserialize(string data) { int i = 0; return vdfs(data,i); } };

29、将数据流变为多个不相交区间#

Copy
#define x first #define y second typedef pair<int, int> PLL; class SummaryRanges { public: /** Initialize your data structure here. */ set<PLL> S; SummaryRanges() { S.insert({INT_MIN, INT_MIN}), S.insert({INT_MAX, INT_MAX}); } void addNum(int num) { auto r = S.upper_bound({num, INT_MAX}); auto l = r; -- l; if (l->y >= num) return; if (l->y == num - 1 && r->x == num + 1) { S.insert({l->x, r->y}); S.erase(l), S.erase(r); } else if (l->y == num - 1) { S.insert({l->x, num}); S.erase(l); } else if (r->x == num + 1) { S.insert({num, r->y}); S.erase(r); } else { S.insert({num, num}); } } vector<vector<int>> getIntervals() { vector<vector<int>> res; for (auto& p: S) if (p.x != INT_MIN && p.x != INT_MAX) res.push_back({(int)p.x, (int)p.y}); return res; } };

30、左叶子之和#

Copy
class Solution { public: void dfs(TreeNode* root,TreeNode* pre,int& ans){ if(root == nullptr) return; if(!root->left && !root->right && root == pre->left) ans+=root->val; else dfs(root->left,root,ans), dfs(root->right,root,ans); } int sumOfLeftLeaves(TreeNode* root) { int ans = 0; dfs(root,root,ans); return ans; } };

31、N 叉树的层序遍历#

Copy
class Solution { public: vector<vector<int>> levelOrder(Node* root) { vector<vector<int>> ans; if(!root) return ans; queue<Node*> q; q.push(root); while(q.size()){ int n = q.size(); vector<int> temp; while(n--){ auto t = q.front();q.pop(); for(auto& a:t->children){ q.push(a); } temp.push_back(t->val); } ans.push_back(temp); } return ans; } };

32、序列化和反序列化二叉搜索树#

Copy
class Codec { public: void dfs(TreeNode* root,string &ans){ if(root == NULL) return; ans += to_string(root->val) + ' '; dfs(root->left,ans), dfs(root->right,ans); } // Encodes a tree to a single string. string serialize(TreeNode* root) { string ans; dfs(root,ans); return ans; } TreeNode* vdfs(vector<int>& data,int& u,int Max,int Min){ if(u == data.size() || data[u] > Max || data[u] < Min) return NULL; auto root = new TreeNode(data[u++]); root->left = vdfs(data,u,root->val,Min); root->right = vdfs(data,u,Max,root->val); return root; } // Decodes your encoded data to tree. TreeNode* deserialize(string data) { vector<int> d; stringstream sin(data); int n=0, u=0; while(sin>>n) d.push_back(n); return vdfs(d,u,INT_MAX,INT_MIN); } };

33、删除二叉搜索树中的节点#

Copy
class Solution { public: void dfs(TreeNode*& root, int k){ if(!root) return; if(root->val == k){ if(!root->left && !root->right) root=nullptr; else if (!root->left) root = root->right; // 只有右儿子 else if (!root->right) root = root->left; // 只有左儿子 else { auto t = root->left; while(t->right) t = t->right; root->val = t->val; dfs(root->left,t->val); } }else if(root->val < k) dfs(root->right,k); else dfs(root->left,k); } TreeNode* deleteNode(TreeNode* root, int key) { dfs(root,key); return root; } };

34、二叉搜索树中的众数【×】#

Copy
class Solution { public: vector<int> ans; int maxc = 0, curc = 0, last; void dfs(TreeNode*root){ if(root == nullptr) return; dfs(root->left); if (!curc || root->val == last) { curc ++; last = root->val; } else { last = root->val; curc = 1; } if (curc > maxc) ans = {last}, maxc = curc; else if (curc == maxc) ans.push_back(last); dfs(root->right); } vector<int> findMode(TreeNode* root) { dfs(root); return ans; } };

35、找树左下角的值#

Copy
// bfs class Solution { public: int findBottomLeftValue(TreeNode* root) { int ans; queue<TreeNode*> q; q.push(root); while(q.size()){ auto t = q.front(); ans = t->val; int n = q.size(); while(n--){ t = q.front(); q.pop(); if(t->left) q.push(t->left); if(t->right) q.push(t->right); } } return ans; } }; // dfs class Solution { public: int maxd = 0,ans = 0; int findBottomLeftValue(TreeNode* root) { dfs(root,1); return ans; } void dfs(TreeNode*root,int d){ if(!root) return; if(d > maxd){ maxd = d; ans = root->val; }dfs(root->left,d+1), dfs(root->right,d+1); } };

36、在每个树行中找最大值#

Copy
class Solution { public: unordered_map<int, int> hash; int maxd = 0; vector<int> largestValues(TreeNode* root) { dfs(root, 1); vector<int> res; for (int i = 1; i <= maxd; i ++ ) res.push_back(hash[i]); return res; } void dfs(TreeNode* root, int d) { if (!root) return; maxd = max(maxd, d); if (hash.count(d) == 0) hash[d] = root->val; else hash[d] = max(hash[d], root->val); dfs(root->left, d + 1); dfs(root->right, d + 1); } };

37、奇偶树#

Copy
class Solution { public: bool isEvenOddTree(TreeNode* root) { queue<TreeNode*> q; if (root) q.push(root); int level = 0; while (!q.empty()) { int len = q.size(); int value = (level == 0) ? INT_MIN : INT_MAX; while (len--) { auto cur = q.front(); q.pop(); if ((level == 0) && (cur->val % 2 == 0 || cur->val <= value) || (level == 1) && (cur->val % 2 == 1 || cur->val >= value)) return false; value = cur->val; if (cur->left) q.push(cur->left); if (cur->right) q.push(cur->right); } level ^= 1; } return true; } };

[Go Back~~](# LeetCode题解)

chap-5: Trie树(字典树)#

1、实现 Trie (前缀树)#

Copy
class Trie { public: struct Node{ Node * nxt[26]; bool end; Node(){ for(int i=0;i<26;i++) nxt[i] = NULL; end = false; } }; Node* data; /** Initialize your data structure here. */ Trie() { data = new Node(); } /** Inserts a word into the trie. */ void insert(string word) { auto t = data; for(auto& c:word){ if(t->nxt[c-'a'] == NULL) t->nxt[c-'a'] = new Node(); t = t->nxt[c - 'a']; } t->end = true; } /** Returns if the word is in the trie. */ bool search(string word) { auto t = data; for(auto& c:word){ if(t->nxt[c-'a']) t = t->nxt[c - 'a']; else return false; } return t->end == true; } /** Returns if there is any word in the trie that starts with the given prefix. */ bool startsWith(string prefix) { auto t = data; for(auto& c:prefix){ if(t->nxt[c-'a']) t = t->nxt[c - 'a']; else return false; } return true; } };

2、添加与搜索单词 - 数据结构设计#

Copy
class WordDictionary { public: struct Node{ Node* nxt[26]; bool end; Node(){ for(int i = 0;i<26;i++) nxt[i] = NULL; end = false; } }*root; /** Initialize your data structure here. */ WordDictionary() { root = new Node(); } void addWord(string word) { auto t = root; for(auto &c:word){ if(t->nxt[c - 'a'] == NULL) t->nxt[c-'a'] = new Node(); t = t->nxt[c - 'a']; } t->end = true; } bool dfs(Node* t,string& word,int u){ if(!t || u == word.size()) return false; if(word[u] != '.'){ if(t->nxt[word[u] - 'a'] == NULL) return false; else if(u == word.size() - 1) return t->nxt[word[u] - 'a']->end == true; else return dfs(t->nxt[word[u] - 'a'],word,u+1); }else{ auto f = false; for(auto i = 0;i<26;i++){ if(t->nxt[i]) if(u == word.size() -1 && t->nxt[i]->end) return true; else f |= dfs(t->nxt[i],word,u+1); } return f; } } bool search(string word) { auto t = root; return dfs(t,word,0); } };

3、单词搜索 II#

Copy
// board建立trie树 class Solution { public: struct Node{ Node* nxt[26]; Node(){ for(auto i = 0;i<26;i++) nxt[i] = NULL; } }*root; int col[4] = {1,0,-1,0}, row[4] = {0,1,0,-1}; vector<vector<bool>> f; void dfs(Node* t,vector<vector<char>>& board, int i,int j,int u,int cnt){ if(u == cnt) return; for(int k = 0;k<4;k++){ int x = i+row[k], y = j+col[k]; if(x>=0 && x<board.size() && y>=0 && y<board[0].size() && !f[x][y]){ auto temp = t; if(t->nxt[board[x][y] -'a'] == NULL) t->nxt[board[x][y] -'a'] = new Node; temp = t->nxt[board[x][y] -'a']; f[x][y] = true; dfs(temp,board,x,y,u+1,cnt); f[x][y] = false; } } } bool search(Node* t,string& word){ for(auto &c:word){ if(t->nxt[c - 'a'] == NULL) return false; else t = t->nxt[c - 'a']; } return true; } vector<string> findWords(vector<vector<char>>& board, vector<string>& words) { root = new Node(); f = vector<vector<bool>>(board.size(),vector<bool>(board[0].size(),false)); int cnt = 0; vector<string> ans; for(auto &word:words) cnt = max(cnt,(int)word.size()); for(int i = 0;i<board.size();i++){ for(int j = 0;j<board[0].size();j++){ auto t = root; if(t->nxt[board[i][j] -'a'] == NULL) t->nxt[board[i][j] -'a'] = new Node; t = t->nxt[board[i][j] -'a']; f[i][j] = true; dfs(t,board,i,j,1,cnt); f[i][j] = false; } } for(auto &word:words){ auto t = root; if(word.size() <= board.size()*board[0].size() && search(t,word)) ans.push_back(word); } return ans; } }; // words建trie树 class Solution { public: struct Node { int id; Node *son[26]; Node() { id = -1; for (int i = 0; i < 26; i ++ ) son[i] = NULL; } }*root; unordered_set<int> ids; vector<vector<char>> g; int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; void insert(string& word, int id) { auto p = root; for (auto c: word) { int u = c - 'a'; if (!p->son[u]) p->son[u] = new Node(); p = p->son[u]; } p->id = id; } vector<string> findWords(vector<vector<char>>& board, vector<string>& words) { g = board; root = new Node(); for (int i = 0; i < words.size(); i ++ ) insert(words[i], i); for (int i = 0; i < g.size(); i ++ ) for (int j = 0; j < g[i].size(); j ++ ) { int u = g[i][j] - 'a'; if (root->son[u]) dfs(i, j, root->son[u]); } vector<string> res; for (auto id: ids) res.push_back(words[id]); return res; } void dfs(int x, int y, Node* p) { if (p->id != -1) ids.insert(p->id); char t = g[x][y]; g[x][y] = '.'; for (int i = 0; i < 4; i ++ ) { int a = x + dx[i], b = y + dy[i]; if (a >= 0 && a < g.size() && b >= 0 && b < g[0].size() && g[a][b] != '.') { int u = g[a][b] - 'a'; if (p->son[u]) dfs(a, b, p->son[u]); } } g[x][y] = t; } };

4、数组中两个数的最大异或值#

Copy
class Solution { public: struct Node{ Node* nxt[2]; Node(){ nxt[0] = NULL; nxt[1] = NULL; } }; int findMaximumXOR(vector<int>& nums) { int ans = 0; if(nums.size() == 1) return ans; auto root = new Node(); for(auto&num:nums) { auto t = root; bitset<32> n = num; for(int i = 31;~i;i--){ if(t->nxt[n[i]] == NULL) t->nxt[n[i]] = new Node; t = t->nxt[n[i]]; } } for(auto&num:nums) { auto t = root; bitset<32> n = num; int b = 0; for(int i = 31;~i;i--){ if(t->nxt[~n[i]]){ b = (b<<1) + ~n[i]; t = t->nxt[~n[i]]; }else { b = (b<<1) + n[i]; t = t->nxt[n[i]]; } } ans = max(ans,num^b); } return ans; } };

[Go Back~~](# LeetCode题解)

chap-6: 堆#

1、数组中的第K个最大元素#

Copy
// 堆 class Solution { public: vector<int> tree; void adjust(int root,int k){ auto t = tree[root], j = 2*root+1; while(j<k){ if(j+1<k && tree[j+1] < tree[j]) j++; if(tree[j] > t) break; tree[(j-1)/2] = tree[j]; j = 2*j+1; } tree[(j-1)/2] = t; } int findKthLargest(vector<int>& nums, int k) { int n = nums.size(), i = 0; tree = vector<int>(k); for(i = 0;i<k;i++) tree[i] = nums[i]; for(i = k/2;~i;i--) adjust(i,k); for(i = k;i<n;i++){ if(nums[i] > tree[0]) tree[0] = nums[i], adjust(0,k); } return tree[0]; } }; // api-优先队列 class Solution { public: int findKthLargest(vector<int>& nums, int k) { priority_queue<int,vector<int>,greater<int>> help; for(auto &num:nums){ help.push(num); if(help.size() > k) help.pop(); } return help.top(); } }; // 快排 class Solution { public: int quick_sort(vector<int>& nums,int x,int y,int k){ if(x == y) return nums[k]; int l = x-1, r = y+1; auto q = nums[x]; while(l < r){ do l++; while(nums[l] > q); do r--; while(nums[r] < q); if(l<r) swap(nums[l],nums[r]); } if(k <= r) return quick_sort(nums,x,r,k); else return quick_sort(nums,r+1,y,k); } int findKthLargest(vector<int>& nums, int k) { return quick_sort(nums,0,nums.size()-1,k-1); } }; // 库函数 class Solution { public: int findKthLargest(vector<int>& nums, int k) { nth_element(nums.begin(),nums.begin()+((int)nums.size() - k),nums.end()); return nums[(int)nums.size() - k]; } };

2、数据流的中位数【对顶堆】#

Copy
// 如果数据流中所有整数都在 0 到 100 范围内,你将如何优化你的算法? [计数排序,vector<int>(100)] // 如果数据流中 99% 的整数都在 0 到 100 范围内,你将如何优化你的算法? [计数排序,增开[-INT_max,0)与(101,INT_max]] class MedianFinder { public: /** initialize your data structure here. */ priority_queue<int> big; priority_queue<int,vector<int>,greater<int>> small; MedianFinder() { } void addNum(int num) { if(big.empty() || num <= big.top()) big.push(num); else small.push(num); if(big.size() == small.size() + 2){ auto t = big.top(); big.pop(); small.push(t); }else if(small.size() == big.size()+1){ auto t = small.top(); small.pop(); big.push(t); } } double findMedian() { if(big.size() == small.size()) return (big.top()+small.top())/2.0; else return big.top(); } };

3、滑动窗口中位数 【对顶堆】#

Copy
class Solution { public: multiset<int> left,right; int k; double find_m(){ if(k%2) return *right.begin(); else return ((double)*left.rbegin() + *right.begin())/2; } vector<double> medianSlidingWindow(vector<int>& nums, int k_) { k = k_; vector<double> ans; for(int i = 0;i<k;i++) right.insert(nums[i]); for(int i = 0;i<k/2;i++) { auto t = *right.begin(); left.insert(t); right.erase(right.find(t)); } ans.push_back(find_m()); for(int i=k;i<nums.size();i++){ auto a = nums[i], b = nums[i-k]; if(a >= *right.begin()) right.insert(a); else left.insert(a); if(right.find(b) != right.end()){ right.erase(right.find(b)); }else left.erase(left.find(b)); while(right.size() > left.size() + 1){ // 此处有别于第二题 a = *right.begin(); right.erase(right.find(a)); left.insert(a); } while(left.size() > right.size()){ // 此处有别于第二题 a = *left.rbegin(); left.erase(left.find(a)); right.insert(a); } ans.push_back(find_m()); } return ans; } };

4、前 K 个高频元素#

Copy
class Solution { public: static bool mycmp(const pair<int,int> &a,const pair<int,int> & b) { return a.second > b.second; } vector<int> topKFrequent(vector<int>& nums, int k) { unordered_map<int,int> m; for(auto &num:nums) m[num]++; vector<pair<int,int>> t(m.begin(),m.end()); sort(t.begin(),t.end(),mycmp); vector<int> ans; while(k--){ ans.push_back(t[k].first); } return ans; } };

5、查找和最小的K对数字【多路归并】#

Copy
class Solution { public: typedef pair<int,int> pii; vector<vector<int>> kSmallestPairs(vector<int>& a, vector<int>& b, int k) { vector<vector<int>> ans; priority_queue<pii,vector<pii>,greater<pii>> help; for(int j=0;j<b.size();j++) help.push(make_pair(a[0]+b[j],0)); while(k-- && help.size()){ auto t = help.top(); help.pop(); ans.push_back({a[t.second],t.first - a[t.second]}); if(t.second+1 < a.size()) help.push(make_pair(t.first - a[t.second] + a[t.second+1],t.second+1)); } return ans; } };

6、根据字符出现频率排序【topK】#

Copy
class Solution { public: typedef pair<int,char> pic; string frequencySort(string s) { unordered_map<char,int> hash; for(auto c:s) hash[c]++; priority_queue<pic> t; for(auto &c:hash){ t.push(make_pair(c.second,c.first)); } string ans; while(t.size()){ auto c = t.top(); while(c.first--) ans += c.second; t.pop(); } return ans; } };

[Go Back~~](# LeetCode题解)

posted @   SrtFrmGNU  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示
CONTENTS