###### tags: `Weekly Contest` # Weekly Contest 132 ## [1025. Divisor Game](https://leetcode.com/problems/divisor-game/) (<font color=#00B8A3>Easy</font>) 限制 : <ul> <li><code>1 <= n <= 1000</code></li> </ul> ### Solution #### 時間複雜度: $O(N)$ #### 空間複雜度: $O(1)$ 程式碼: ```c++= class Solution { public: bool divisorGame(int n) { bool isAlice = false; while (true) { int temp = n; for (int i = 1; i < n; i++) { if (temp % i == 0) { temp = temp - i; isAlice = !isAlice; break; } } if (n == temp) return isAlice; else n = temp; } } }; ``` ## [1026. Maximum Difference Between Node and Ancestor](https://leetcode.com/problems/maximum-difference-between-node-and-ancestor/) (<font color=#FFC011>Medium</font>) 限制 : <ul> <li><code>The number of nodes in the tree is in the range [2, 5000].</code></li> <li><code>0 <= Node.val <= 10<sup>5</sup></code></li> </ul> ### Solution #### 時間複雜度: $O(log(N))$ #### 空間複雜度: $O(log(N))$ 程式碼: ```c++= class Solution { public: int findValue(TreeNode* root, int maxNum, int minNum) { maxNum = max(maxNum, root->val); minNum = min(minNum, root->val); int result = maxNum - minNum; if(root->left == nullptr && root->right == nullptr) { return result; } int leftValue = INT_MIN; int rightValue = INT_MIN; if(root->left ) leftValue = findValue(root->left, maxNum, minNum); if(root->right ) rightValue = findValue(root->right, maxNum, minNum); result = max(result, leftValue); result = max(result, rightValue); return result; } int maxAncestorDiff(TreeNode* root) { return findValue(root, INT_MIN, INT_MAX); } }; ``` ## [1027. Longest Arithmetic Subsequence](https://leetcode.com/problems/longest-arithmetic-subsequence/)(<font color=#FFC011>Medium</font>) 限制 : <ul> <li><code>2 <= nums.length <= 1000</code></li> <li><code>0 <= nums[i] <= 500</code></li> </ul> ### Solution 這題要找的是找到最長的 subsequence ,符合等差數列。 由於這題的長度不長,所以直接暴力解就好。 #### 時間複雜度: $O(N^3)$ #### 空間複雜度: $O(1)$ 程式碼: ```c++= class Solution { public: int longestArithSeqLength(vector<int>& nums) { int maxLen = 0; for (int i = 0; i < nums.size(); i++) { for (int j = i + 1; j < nums.size(); j++) { int d = nums[j] - nums[i]; int l = 2; int nowNum = nums[j]; for (int k = j + 1; k < nums.size(); k++) { if (nums[k] == nowNum + d) { nowNum = nums[k]; l++; } } maxLen = max(maxLen, l); } } return maxLen; } }; ``` ## [1028. Recover a Tree From Preorder Traversal](https://leetcode.com/problems/recover-a-tree-from-preorder-traversal)(<font color=#FF375F>Hard</font>) 限制 : <ul> <li><code>The number of nodes in the original tree is in the range [1, 1000]. </code></li> <li><code>1 <= Node.val <= 10<sup>9</sup> </code></li> </ul> ### Solution - 參考至[這個影片](https://youtu.be/QRSDXF8ZrmE?si=CBDneq_KTffy_tKG) - 這題是要從一個含有紀錄的字串,轉換回一顆 binary tree。字串內容分別有"-"和阿拉伯數字,"-"代表的是後面阿拉伯數字所在的level,阿拉伯數字則代表這個 node 的數值。 - 在這裡由於題目所使用的是DFS,traversal 的順序是 中->左->右節點。我們要用這個特性來建立一個 stack ,方便我們替node找到合適的位置 - 演算法的過程:對每一個的"-X"的一串數字做處理,重新回復成數字和層數,再利用 stack 找到自己的父節點,駔後再存放進去。 #### 時間複雜度: $O(n)$ #### 空間複雜度: $O(n)$ 程式碼: ```c++= class Solution { public: // 利用 stk 把樹的其中一部份記起來 // 因為下一個數字與前面數字有子樹的關係,而且左子樹一定先。所以 stk // 可以很方便 traversal。 注意因為是 DFS,所以這方法才可以用。 TreeNode* recoverFromPreorder(string traversal) { vector<TreeNode*> stk; for (int i = 0, level, val; i < traversal.size();) { for (level = 0; traversal[i] == '-'; i++) { level++; } for (val = 0; i < traversal.size() && traversal[i] != '-'; i++) { val = val * 10 + traversal[i] - '0'; } TreeNode* node = new TreeNode(val); // 找到和上面數字的父 node while (stk.size() > level) stk.pop_back(); if (stk.size() > 0) if (stk.back()->left == nullptr) stk.back()->left = node; else stk.back()->right = node; stk.push_back(node); } return stk[0]; } }; ```