# LeetCode Everyday for Beginner 2 contributed by <`Charlie-Tsai1123`> , <`xiusobeee`> | <font color="#46c6c2">**Easy 14**</font> | <font color="#fac31d">**Medium 36**</font> | <font color="#f8615c">**Hard 7**</font> | (7/19) >[!Note] reference >[代碼隨想錄 - 教材](https://gitee.com/programmercarl/leetcode-master#/programmercarl/leetcode-master/blob/master/./problems/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.md) >[代碼隨想錄 - 題目](https://github.com/youngyangyang04/leetcode-master/tree/master/problems) ## 7/19 ### [131. Palindrome Partitioning](https://leetcode.com/problems/palindrome-partitioning/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `String` `Dynamic Programming` `Backtracking` * <font color="#2DB55D">**AC** (66ms) | **Beats** 26.54%</font> * $O(n \times 2 ^n)$ ```cpp class Solution { public: vector<vector<string>> ans; vector<string> ans_element; bool isPalindrome(string s) { int left = 0, right = s.length() - 1; while (right > left) { if (s[left] != s[right]) return false; left++; right--; } return true; } void backTracing(string s) { if (s == "") { ans.push_back(ans_element); } string tmp = ""; for (int i = 0; i < s.length(); i++) { tmp.push_back(s[i]); if (isPalindrome(tmp)) { ans_element.push_back(tmp); backTracing(s.substr(i + 1, s.length() - i - 1)); ans_element.pop_back(); } } } vector<vector<string>> partition(string s) { backTracing(s); return ans; } }; ``` --- >[!Note]優化兩個地方 >1. 判斷 palindrome 原本的 code 會重複判斷到 >2. function 傳入改成 const string& s 可以不用複製整個 s 到 function * <font color="#2DB55D">**AC** (50ms) | **Beats** 56.70%</font> * $O(n \times 2 ^n)$ ```cpp class Solution { public: vector<vector<string>> ans; vector<string> ans_element; vector<vector<bool>> isPalindrome; void computePalindrome(const string& s) { isPalindrome.resize(s.length(), vector<bool>(s.length(), false)); for (int i = s.length() - 1; i >= 0; i--) { for (int j = i; j < s.length(); j++) { if (i == j) { isPalindrome[i][j] = true; } else if (j - i == 1) { isPalindrome[i][j] = (s[i] == s[j]); } else { isPalindrome[i][j] = (s[i] == s[j] && isPalindrome[i + 1][j - 1]); } } } } void backTracing(const string& s, int startIndex) { if (startIndex == s.length()) { ans.push_back(ans_element); return; } for (int i = startIndex; i < s.length(); i++) { if (isPalindrome[startIndex][i]) { ans_element.push_back(s.substr(startIndex, i - startIndex + 1)); backTracing(s, i + 1); ans_element.pop_back(); } } } vector<vector<string>> partition(string s) { computePalindrome(s); backTracing(s, 0); return ans; } }; ``` --- ### [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Two Pointers` `String` `Dynamic Programming` * <font color="#2DB55D">**AC** (31ms) | **Beats** 30.42%</font> * $O(n^2)$ ```cpp class Solution { public: int countSubstrings(string s) { vector<vector<bool>> dp(s.length(), vector<bool>(s.length(), false)); int ans = 0; for (int i = s.size() - 1; i >= 0; i--) { for (int j = i; j < s.size(); j++) { dp[i][j] = (i == j) || ((j - i == 1) && s[i] == s[j]) || ((j - i > 1) && s[i] == s[j] && dp[i + 1][j - 1]); if (dp[i][j]) ans++; } } return ans; } }; ``` ## 7/20 ### [132. Palindrome Partitioning II](https://leetcode.com/problems/palindrome-partitioning-ii/description/) <font color="#f8615c">**Hard**</font> ==Topics== : `String` `Dynamic Programming` * <font color="#2DB55D">**AC** (52ms) | **Beats** 77.74%</font> * $O(n^2)$ ```cpp class Solution { public: int minCut(string s) { vector<vector<bool>> isPalindrome(s.length(), vector<bool>(s.length(), false)); for (int i = s.length() - 1; i >= 0; i--) { for (int j = i; j < s.length(); j++) { if (j - i <= 1) isPalindrome[i][j] = (s[i] == s[j]); else isPalindrome[i][j] = (s[i] == s[j] && isPalindrome[i + 1][j - 1]); } } vector<int> cut(s.length(), 0); for (int i = 0; i < s.length(); i++) cut[i] = i; for (int i = 1; i < s.length(); i++) { if (isPalindrome[0][i]) { cut[i] = 0; continue; } for (int j = 0; j < i; j++) { if (isPalindrome[j + 1][i]) { cut[i] = min(cut[i], cut[j] + 1); } } } return cut[s.length() - 1]; } }; ``` ### [134. Gas Station](https://leetcode.com/problems/gas-station/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Greedy` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $O(n)$ #### Method 1 ```cpp class Solution { public: int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { int curSum = 0, min = INT_MAX; for (int i = 0; i < gas.size(); i++) { int rest = gas[i] - cost[i]; curSum += rest; if (curSum < min) { min = curSum; } } if (min > 0) return 0; if (curSum < 0) return -1; for (int i = gas.size() - 1; i >= 0; i--) { int rest = gas[i] - cost[i]; min += rest; if (min >= 0) return i; } return -1; } }; ``` #### Method 2 --- >[!Caution]錯誤沒檢查 total sum 是否小於 0 ```cpp class Solution { public: int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { int curSum = 0, startIndex = 0; for (int i = 0; i < gas.size(); i++) { int rest = gas[i] - cost[i]; curSum += rest; if (curSum < 0) { curSum = 0; startIndex = i + 1; } } return (startIndex == gas.size()) ? -1 : startIndex; } }; ``` 修正版 ```cpp class Solution { public: int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { int curSum = 0, startIndex = 0, totalSum = 0; for (int i = 0; i < gas.size(); i++) { int rest = gas[i] - cost[i]; curSum += rest; totalSum += rest; if (curSum < 0) { curSum = 0; startIndex = i + 1; } } return (totalSum < 0) ? -1 : startIndex; } }; ``` --- ## 7/22 ### [135. Candy](https://leetcode.com/problems/candy/description/) <font color="#f8615c">**Hard**</font> ==Topics== : `Array` `Greedy` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $O(n)$ --- 錯誤作法一次考慮 ```cpp class Solution { public: int candy(vector<int>& ratings) { int last_candy = 1, sum = 1, min = 1; for (int i = 1; i < ratings.size(); i++) { cout << last_candy << " "; if (ratings[i] <= ratings[i - 1]) { last_candy--; } else { last_candy++; } sum += last_candy; if (last_candy < min) min = last_candy; } cout << last_candy << endl; sum += (1 - min) * ratings.size(); return sum; } }; ``` ```tex ratings =[1,3,2,2,1] stdout = 1 2 1 0 -1 ``` --- 正確做法 : 分成兩邊考慮 ```cpp class Solution { public: int candy(vector<int>& ratings) { vector<int> candies(ratings.size(), 1); int sum; for (int i = 1; i < ratings.size(); i++) { if (ratings[i] > ratings[i - 1]) candies[i] = candies[i - 1] + 1; } sum = candies[ratings.size() - 1]; for (int i = ratings.size() - 2; i >= 0; i--) { if (ratings[i] > ratings[i + 1]) candies[i] = max(candies[i + 1] + 1, candies[i]); sum += candies[i]; } return sum; } }; ``` ## 8/5 ### [509. Fibonacci Number](https://leetcode.com/problems/fibonacci-number/description/) <font color="#46c6c2">**Easy**</font> ==Topics== : `Math` `Dynamic Programming` `Recursion` `Memoization` #### Method 1 * <font color="#2DB55D">**AC** (3ms) | **Beats** 66.48%</font> * $Time: O(n)$ * $Space: O(n)$ ```cpp class Solution { public: int fib(int n) { vector<int> dp(max(n + 1, 2)); dp[0] = 0; dp[1] = 1; for (int i = 2; i <= n; i++) { dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n]; } }; ``` #### Method 2 * <font color="#2DB55D">**AC** (2ms) | **Beats** 77.67%</font> * $Time: O(n)$ * $Space: O(1)$ ```cpp class Solution { public: int fib(int n) { if (n == 0) return 0; int dp[2]; dp[0] = 0; dp[1] = 1; for (int i = 2; i <= n; i++) { int sum = dp[0] + dp[1]; dp[0] = dp[1]; dp[1] = sum; } return dp[1]; } }; ``` ### [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/description/) <font color="#46c6c2">**Easy**</font> ==Topics== : `Math` `Dynamic Programming` `Memoization` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(n)$ ```cpp class Solution { public: int climbStairs(int n) { vector<int> dp(max(n, 2)); dp[0] = 1; dp[1] = 2; for (int i = 2; i < n; i++) { dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n - 1]; } }; ``` ### [746. Min Cost Climbing Stairs](https://leetcode.com/problems/min-cost-climbing-stairs/description/) <font color="#46c6c2">**Easy**</font> ==Topics== : `Math` `Dynamic Programming` `Memoization` #### Method 1 * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(n)$ ```cpp class Solution { public: int minCostClimbingStairs(vector<int>& cost) { vector<int> dp(cost.size() + 1); dp[0] = 0; dp[1] = 0; for (int i = 2; i < dp.size(); i++) { dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]); } return dp[dp.size() - 1]; } }; ``` #### Method 2 * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(1)$ ```cpp class Solution { public: int minCostClimbingStairs(vector<int>& cost) { int dp[2]; dp[0] = 0; dp[1] = 0; for (int i = 2; i <= cost.size(); i++) { int sum = min(dp[0] + cost[i - 2], dp[1] + cost[i - 1]); dp[0] = dp[1]; dp[1] = sum; } return dp[1]; } }; ``` ## 8/6 ### [343. Integer Break](https://leetcode.com/problems/integer-break/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Math` `Dynamic Programming` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n^2)$ * $Space: O(n)$ >[!Note]思考為什麼 iterate 的範圍可以是 i / 2 ```cpp class Solution { public: int integerBreak(int n) { vector<int> dp(n + 1, 0); dp[1] = 1; dp[2] = 1; for (int i = 3; i <= n; i++) { for (int j = 1; j <= i / 2; j++) { dp[i] = max({dp[i], dp[i - j] * j, j * (i - j)}); } } return dp[n]; } }; ``` ### [416. Partition Equal Subset Sum](https://leetcode.com/problems/partition-equal-subset-sum/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` * <font color="#2DB55D">**AC** (63ms) | **Beats** 89.84%</font> * $Time: O(n^2)$ * $Space: O(n)$ ```cpp class Solution { public: bool canPartition(vector<int>& nums) { int space = 0; for (int a: nums) space += a; if (space % 2 == 1) return false; space /= 2; vector<int> dp(space + 1); for (int i = 0; i < nums.size(); i++) { for (int j = space; j >= nums[i]; j--) { dp[j] = max(dp[j], nums[i] + dp[j - nums[i]]); } } return dp[space] == space; } }; ``` ### [1049. Last Stone Weight II](https://leetcode.com/problems/last-stone-weight-ii/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` `Weekly Contest 137` * <font color="#2DB55D">**AC** (2ms) | **Beats** 59.13%</font> * $Time: O(n^2)$ * $Space: O(n)$ ```cpp class Solution { public: int lastStoneWeightII(vector<int>& stones) { int sum = 0; for (int a: stones) sum += a; vector<int> dp(sum / 2 + 1, 0); for (int i = 0; i < stones.size(); i++) { for (int j = sum / 2; j >= stones[i]; j--) { dp[j] = max(dp[j], stones[i] + dp[j - stones[i]]); } } return sum - 2 * dp[sum / 2]; } }; ``` ## 8/7 ### [494. Target Sum](https://leetcode.com/problems/target-sum/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` `Backtracking` * <font color="#2DB55D">**AC** (3ms) | **Beats** 87.76%</font> * $Time: O(n^2)$ * $Space: O(n)$ >[!Note] 這題難點在初始化部分要想清楚 ```cpp class Solution { public: int findTargetSumWays(vector<int>& nums, int target) { int capacity = target; for (int a: nums) capacity += a; if (capacity < 0) return 0; vector<int> dp(capacity + 1, 0); dp[0] = 1; for (int i = 0; i < nums.size(); i++) { for (int j = capacity; j >= 2 * nums[i]; j--) { dp[j] = dp[j] + dp[j - 2 * nums[i]]; } } return dp[capacity]; } }; ``` * <font color="#2DB55D">**AC** (2ms) | **Beats** 90.15%</font> * $Time: O(n^2)$ * $Space: O(n)$ >[!Note] 可以想想看背包空間要如何解釋 ```cpp class Solution { public: int findTargetSumWays(vector<int>& nums, int target) { int capacity = target; for (int a: nums) capacity += a; if (capacity < 0 || capacity % 2 == 1) return 0; capacity /= 2; vector<int> dp(capacity + 1, 0); dp[0] = 1; for (int i = 0; i < nums.size(); i++) { for (int j = capacity; j >= nums[i]; j--) { dp[j] = dp[j] + dp[j - nums[i]]; } } return dp[capacity]; } }; ``` ### [474. Ones and Zeroes](https://leetcode.com/problems/ones-and-zeroes/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `String` `Dynamic Programming` * <font color="#2DB55D">**AC** (50ms) | **Beats** 85.49%</font> * $Time: O(kmn)$ * $Space: O(mn)$ ```cpp class Solution { public: int findMaxForm(vector<string>& strs, int m, int n) { vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0)); for (string s: strs) { int numZero = 0, numOne = 0; for (int i = 0; i < s.length(); i++) { if (s[i] == '0') numZero++; else numOne++; } for (int i = m; i >= numZero; i--) { for (int j = n; j >= numOne; j--) { dp[i][j] = max(dp[i][j], 1 + dp[i - numZero][j - numOne]); } } } return dp[m][n]; } }; ``` ### [518. Coin Change II](https://leetcode.com/problems/coin-change-ii/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` * <font color="#2DB55D">**AC** (3ms) | **Beats** 95.26%</font> * $Time: O(n^2)$ * $Space: O(n)$ ```cpp class Solution { public: int change(int amount, vector<int>& coins) { vector<uint64_t> dp(amount + 1, 0); dp[0] = 1; for (int i = 0; i < coins.size(); i++) { for (int j = coins[i]; j <= amount; j++) { dp[j] += dp[j - coins[i]]; } } return dp[amount]; } }; ``` ## 8/8 ### [377. Combination Sum IV](https://leetcode.com/problems/combination-sum-iv/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n^2)$ * $Space: O(n)$ --- >[!Warning] 錯誤作法: 先遍歷物品是組合 ```cpp class Solution { public: int combinationSum4(vector<int>& nums, int target) { vector<int> dp(target + 1, 0); dp[0] = 1; for (int i = 0; i < nums.size(); i++) { for (int j = nums[i]; j <= target; j++) { dp[j] = dp[j] + dp[j - nums[i]]; } } return dp[target]; } }; ``` --- >[!Warning] 正確做法: 先遍歷背包式排列 ```cpp class Solution { public: int combinationSum4(vector<int>& nums, int target) { vector<uint64_t> dp(target + 1, 0); dp[0] = 1; for (int i = 0; i <= target; i++) { for (int j = 0; j < nums.size(); j++) { if (nums[j] > i) continue; dp[i] = dp[i] + dp[i - nums[j]]; } } return dp[target]; } }; ``` ## 8/9 ### [322. Coin Change](https://leetcode.com/problems/coin-change/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` `Breadth-First Search` * <font color="#2DB55D">**AC** (19ms) | **Beats** 83.84%</font> * $Time: O(n^2)$ * $Space: O(n)$ --- >[!Warning]錯誤作法 >1. 沒考慮若無法組成 amount 如何處理 >2. 因為一開始就初始化 dp 數組為 0 也沒考慮若 amount 就是 0 的情況 ```cpp class Solution { public: int coinChange(vector<int>& coins, int amount) { vector<int> dp(amount + 1, 0); for (int i = 0; i < coins.size(); i++) { for (int j = coins[i]; j >= amount; j++) { if (dp[j] == 0) { dp[j] = 1 + dp[j - coins[i]]; } else { dp[j] = min(dp[j], 1 + dp[j - coins[i]]); } } } return dp[amount]; } }; ``` --- ```cpp class Solution { public: int coinChange(vector<int>& coins, int amount) { if (amount == 0) return 0; vector<int> dp(amount + 1, 0); for (int i = 0; i < coins.size(); i++) { for (int j = coins[i]; j <= amount; j++) { if (dp[j - coins[i]] == 0 && j - coins[i] != 0) continue; if (dp[j] == 0) { dp[j] = 1 + dp[j - coins[i]]; } else { dp[j] = min(dp[j], 1 + dp[j - coins[i]]); } } } return (dp[amount] == 0) ? -1 : dp[amount]; } }; ``` ### [279. Perfect Squares](https://leetcode.com/problems/perfect-squares/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` `Breadth-First Search` * <font color="#2DB55D">**AC** (39ms) | **Beats** 85.65%</font> * $Time: O(n^2)$ * $Space: O(n)$ ```cpp class Solution { public: int numSquares(int n) { vector<int> dp(n + 1, INT_MAX); dp[0] = 0; for (int i = 1; i <= sqrt(n); i++) { for (int j = i * i; j <= n; j++) { dp[j] = min(dp[j], 1 + dp[j - i * i]); } } return dp[n]; } }; ``` ## 8/10 ### [377. Combination Sum IV](https://leetcode.com/problems/combination-sum-iv/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Hash Table` `String` `Dynamic Programming` `Trie` `Memoization` * <font color="#2DB55D">**AC** (15ms) | **Beats** 33.93%</font> * $Time: O(n^3)$ * $Space: O(n)$ >[!Note] substr 本身的時間複雜度就是 O(n) >這題值得再思考一次他的做法 ```cpp class Solution { public: bool wordBreak(string s, vector<string>& wordDict) { unordered_set<string> wordSet(wordDict.begin(), wordDict.end()); vector<bool> dp(s.length() + 1, false); dp[0] = true; for (int i = 1; i <= s.length(); i++) { for (int j = 0; j < i; j++) { string str = s.substr(j, i - j); if (wordSet.find(str) != wordSet.end() && dp[j] == true) { dp[i] = true; continue; } } } return dp[s.length()]; } }; ``` ## 8/11 ### [198. House Robber](https://leetcode.com/problems/house-robber/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(n)$ >[!Note] 注意 edge cases ```cpp class Solution { public: int rob(vector<int>& nums) { if (nums.size() == 1) return nums[0]; vector<int> dp(nums.size()); dp[0] = nums[0]; dp[1] = max(nums[0], nums[1]); for (int i = 2; i < nums.size(); i++) { dp[i] = max(dp[i - 1], nums[i] + dp[i - 2]); } return dp[nums.size() - 1]; } }; ``` ### [213. House Robber II](https://leetcode.com/problems/house-robber-ii/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(n)$ >[!Note] >1. 思考題目不一定要直接思考,也可以想想可不可以轉換成已知的題目形式 >2. 注意 edge cases 本題還要多思考只有兩個元素的情況 ```cpp class Solution { public: int rob(vector<int>& nums) { if (nums.size() == 1) return nums[0]; if (nums.size() == 2) return max(nums[0], nums[1]); return max(robAction(nums, 0, nums.size() - 2), robAction(nums, 1, nums.size() - 1)); } int robAction(vector<int>& nums, int start, int end) { vector<int> dp(nums.size()); dp[start] = nums[start]; dp[start + 1] = max(nums[start], nums[start + 1]); for (int i = start + 2; i <= end; i++) { dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]); } return dp[end]; } }; ``` ## 8/12 ### [337. House Robber III](https://leetcode.com/problems/house-robber-iii/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Dynamic Programming` `Tree` `Depth-First Search` `Binary Tree` #### Traversal * <font color="#2DB55D">**AC** (11ms) | **Beats** 25.13%</font> * $Time: O(n)$ * $Space: O(n)$ ```cpp /** * 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: unordered_map<TreeNode*, int> visitedNode; int rob(TreeNode* root) { if (visitedNode.find(root) != visitedNode.end()) return visitedNode[root]; int valNotInclude = 0, valInclude = root->val; if (root->left != nullptr) { valNotInclude += rob(root->left); if (root->left->right != nullptr) valInclude += rob(root->left->right); if (root->left->left != nullptr) valInclude += rob(root->left->left); } if (root->right != nullptr) { valNotInclude += rob(root->right); if (root->right->right != nullptr) valInclude += rob(root->right->right); if (root->right->left != nullptr) valInclude += rob(root->right->left); } visitedNode[root] = max(valNotInclude, valInclude); return visitedNode[root]; } }; ``` #### Dynamic programing >[!Warning] Wrong >注意不包括時應該思考的情況 ```cpp /** * 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: int rob(TreeNode* root) { vector<int> dp = robTree(root); return max(dp[0], dp[1]); } vector<int> robTree(TreeNode* cur) { // dp[0] --> not include, dp[1] --> include if (cur == nullptr) return {0, 0}; vector<int> left = robTree(cur->left); vector<int> right = robTree(cur->right); return {left[1] + right[1], left[0] + right[0] + cur->val}; } }; ``` --- * <font color="#2DB55D">**AC** (13ms) | **Beats** 18.46%</font> * $Time: O(n)$ * $Space: O(n)$ ```cpp /** * 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: int rob(TreeNode* root) { vector<int> dp = robTree(root); return max(dp[0], dp[1]); } vector<int> robTree(TreeNode* cur) { // dp[0] --> not include, dp[1] --> include if (cur == nullptr) return {0, 0}; vector<int> left = robTree(cur->left); vector<int> right = robTree(cur->right); int valNotInclude = max(left[0], left[1]) + max(right[0], right[1]); return {valNotInclude, left[0] + right[0] + cur->val}; } }; ``` ## 8/13 ### [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/?source=submission-noac) <font color="#46c6c2">**Easy**</font> ==Topics== : `Array` `Dynamic Programming` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(1)$ ```cpp class Solution { public: int maxProfit(vector<int>& prices) { int buy = prices[0], sold = 0; for (int i = 1; i < prices.size(); i++) { if (prices[i] < buy) buy = prices[i]; else sold = max(sold, prices[i] - buy); } return sold; } }; ``` ## 8/14 ### [123. Best Time to Buy and Sell Stock III](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/?source=submission-noac) <font color="#f8615c">**Hard**</font> ==Topics== : `Array` `Dynamic Programming` * <font color="#2DB55D">**AC** (139ms) | **Beats** 64.04%</font> * $Time: O(n)$ * $Space: O(n)$ ```cpp class Solution { public: int maxProfit(vector<int>& prices) { vector<vector<int>> dp(prices.size(),vector<int>(4, 0)); int max_profit = 0; dp[0][0] = -prices[0]; dp[0][1] = 0; dp[0][2] = -prices[0]; dp[0][3] = 0; for (int i = 1; i < prices.size(); i++) { dp[i][0] = -prices[i]; dp[i][1] = prices[i] + dp[i - 1][0]; dp[i][2] = -prices[i] + dp[i - 1][1]; dp[i][3] = prices[i] + dp[i - 1][2]; max_profit = max({max_profit, dp[i][1], dp[i][3]}); } return max_profit; } }; ``` >[1,2,3,4,5] >output: 2 >expected: 4 ```cpp class Solution { public: int maxProfit(vector<int>& prices) { vector<vector<int>> dp(prices.size(),vector<int>(4, 0)); int max_profit = 0; dp[0][0] = -prices[0]; dp[0][1] = 0; dp[0][2] = -prices[0]; dp[0][3] = 0; for (int i = 1; i < prices.size(); i++) { dp[i][0] = max(dp[i - 1][0], -prices[i]); dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]); dp[i][2] = max(dp[i - 1][2], -prices[i] + dp[i - 1][1]); dp[i][3] = max(dp[i- 1][3], prices[i] + dp[i - 1][2]); max_profit = max({max_profit, dp[i][1], dp[i][3]}); } return max_profit; } }; ``` >別忘記可以選擇什麼都不做 ## 8/15 ### [188. Best Time to Buy and Sell Stock IV](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/description/?source=submission-noac) <font color="#f8615c">**Hard**</font> ==Topics== : `Array` `Dynamic Programming` * <font color="#2DB55D">**AC** (3ms) | **Beats** 86.39%</font> * $Time: O(n \times k)$ * $Space: O(n \times k)$ ```cpp class Solution { public: int maxProfit(int k, vector<int>& prices) { vector<vector<int>> dp(prices.size(), vector<int>(2 * k + 1, 0)); int max_profit = 0; for (int i = 1; i <= k; i++) { dp[0][2 * i - 1] = -prices[0]; } for (int i = 1; i < prices.size(); i++) { for (int j = 1; j <= k; j++) { int id = 2 * j - 1; dp[i][id] = max(dp[i - 1][id], dp[i - 1][id - 1] - prices[i]); dp[i][id + 1] = max(dp[i - 1][id + 1], dp[i - 1][id] + prices[i]); max_profit = max(max_profit, dp[i][id + 1]); } } return max_profit; } }; ``` ### [309. Best Time to Buy and Sell Stock with Cooldown](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(3 \times n)$ ```cpp class Solution { public: int maxProfit(vector<int>& prices) { vector<vector<int>> dp(prices.size(), vector<int>(3, 0)); dp[0][1] = -prices[0]; for (int i = 1; i < prices.size(); i++) { // dp[i][0] => no stock dp[i][0] = max(dp[i - 1][0], dp[i - 1][2]); dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]); dp[i][2] = dp[i - 1][1] + prices[i]; } return max({dp[prices.size() - 1][0], dp[prices.size() - 1][1], dp[prices.size() - 1][2]}); } }; ``` ## 8/17 ### [714. Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` `Greedy` * <font color="#2DB55D">**AC** (95ms) | **Beats** 55.17%</font> * $Time: O(n)$ * $Space: O(2 \times n)$ ```cpp class Solution { public: int maxProfit(vector<int>& prices, int fee) { vector<vector<int>> dp(prices.size(), vector<int>(2)); dp[0][0] = -prices[0]; dp[0][1] = 0; for (int i = 1; i < prices.size(); i++) { dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]); dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee); } return dp[prices.size() - 1][1]; } }; ``` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(1)$ >[!Note] 空間複雜度降低,少了初始化 vector 速度增加 ```cpp class Solution { public: int maxProfit(vector<int>& prices, int fee) { int cur_buy = -prices[0], cur_sold = 0; for (int i = 1; i < prices.size(); i++) { int prev_buy = cur_buy, prev_sold = cur_sold; cur_buy = max(prev_buy, cur_sold - prices[i]); cur_sold = max(prev_sold, cur_buy + prices[i] - fee); } return cur_sold; } }; ``` ## 8/18 ### [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Binary Search` `Dynamic Programming` * <font color="#2DB55D">**AC** (48ms) | **Beats** 74.75%</font> * $Time: O(n^2)$ * $Space: O(n)$ ```cpp class Solution { public: int lengthOfLIS(vector<int>& nums) { vector<int> dp(nums.size(), 1); int result = 1; for (int i = 1; i < nums.size(); i++) { for (int j = 0; j < i; j++) { if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1); } result = max(result, dp[i]); } return result; } }; ``` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n \times log(n))$ * $Space: O(n)$ ```cpp class Solution { public: int lengthOfLIS(vector<int>& nums) { vector<int> subsequence; subsequence.push_back(nums[0]); for (int i = 1; i < nums.size(); i++) { if (nums[i] > subsequence[subsequence.size() - 1]) { subsequence.push_back(nums[i]); continue; } int left = 0, right = subsequence.size(); while (right > left) { int middle = ((right - left) >> 1) + left; if (subsequence[middle] < nums[i]) { left = middle + 1; } else if (subsequence[middle] > nums[i]) { right = middle; } else { left = middle; break; } } subsequence[left] = nums[i]; } return subsequence.size(); } }; ``` ### [674. Longest Continuous Increasing Subsequence](https://leetcode.com/problems/longest-continuous-increasing-subsequence/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(1)$ ```cpp class Solution { public: int findLengthOfLCIS(vector<int>& nums) { int cur_length = 1, max_length = 1; for (int i = 1; i < nums.size(); i++) { if (nums[i] > nums[i - 1]) cur_length++; else cur_length = 1; max_length = max(max_length, cur_length); } return max_length; } }; ``` ### [718. Maximum Length of Repeated Subarray](https://leetcode.com/problems/maximum-length-of-repeated-subarray/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Binary Search` `Dynamic Programming` `Sliding Window` `Rolling Hash` `Hash Function` * <font color="#2DB55D">**AC** (103ms) | **Beats** 31.60%</font> * $Time: O(n \times m)$ * $Space: O(n \times m)$ ```cpp class Solution { public: int findLength(vector<int>& nums1, vector<int>& nums2) { vector<vector<int>> dp(nums1.size() + 1, vector<int>(nums2.size() + 1, 0)); int max_length = 0; for (int i = 1; i <= nums1.size(); i++) { for (int j = 1; j <= nums2.size(); j++) { if (nums1[i - 1] == nums2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1; max_length = max(max_length, dp[i][j]); } } return max_length; } }; ``` * <font color="#2DB55D">**AC** (47ms) | **Beats** 88.61%</font> * $Time: O(n \times m)$ * $Space: O(n)$ >[!Note]使用滾動數組但要注意 >1. 遍歷順序 >2. 注意每次遍歷的狀態變化 ```cpp class Solution { public: int findLength(vector<int>& nums1, vector<int>& nums2) { vector<int> dp(nums2.size() + 1, 0); int result = 0; for (int i = 1; i <= nums1.size(); i++) { for (int j = nums2.size(); j > 0; j--) { if (nums1[i - 1] == nums2[j - 1]) dp[j] = dp[j - 1] + 1; else dp[j] = 0; result = max(result, dp[j]); } } return result; } }; ``` ## 8/21 ### [1143. Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `String` `Dynamic Programming` * <font color="#2DB55D">**AC** (27ms) | **Beats** 83.64%</font> * $Time: O(n \times m)$ * $Space: O(n \times m)$ ```cpp class Solution { public: int longestCommonSubsequence(string text1, string text2) { vector<vector<int>> dp(text1.size() + 1, vector<int>(text2.size() + 1)); int result = 0; for (int i = 1; i <= text1.size(); i++) { for (int j = 1; j <= text2.size(); j++) { if (text1[i - 1] == text2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); } } return dp[text1.size()][text2.size()]; } }; ``` ### [1035. Uncrossed Lines](https://leetcode.com/problems/uncrossed-lines/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Dynamic Programming` `Weekly Contest 134` #### Writing Method (2D) * <font color="#2DB55D">**AC** (5ms) | **Beats** 70.34%</font> * $Time: O(n \times m)$ * $Space: O(n \times m)$ ```cpp class Solution { public: int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) { vector<vector<int>> dp(nums1.size() + 1, vector<int>(nums2.size() + 1, 0)); for (int i = 1; i <= nums1.size(); i++) { for (int j = 1; j <= nums2.size(); j++) { if (nums1[i - 1] == nums2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); } } return dp[nums1.size()][nums2.size()]; } }; ``` #### Writing Method (1D) * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n \times m)$ * $Space: O(m)$ --- >[!Warning] 看看哪裡出錯 ```cpp class Solution { public: int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) { vector<int> dp(nums2.size() + 1, 0); for (int i = 1, prev = 0; i <= nums1.size(); i++) { for (int j = 1; j <= nums2.size(); j++) { int cur = dp[j]; if (nums1[i - 1] == nums2[j - 1]) dp[j] = prev + 1; else dp[j] = max(dp[j], dp[j - 1]); prev = cur; } } return dp[nums2.size()]; } }; ``` >注意初始化 ```diff - for (int i = 1, prev = 0; i <= nums1.size(); i++) + for (int i = 1, prev = 0; i <= nums1.size(); i++, prev = 0) ``` --- ```cpp class Solution { public: int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) { vector<int> dp(nums2.size() + 1, 0); for (int i = 1, prev = 0; i <= nums1.size(); i++, prev = 0) { for (int j = 1; j <= nums2.size(); j++) { int cur = dp[j]; if (nums1[i - 1] == nums2[j - 1]) dp[j] = prev + 1; else dp[j] = max(dp[j], dp[j - 1]); prev = cur; } } return dp[nums2.size()]; } }; ``` >[!Note] 動態規劃 2D 轉為 1D >1. 如果要用到上一個的多個狀態可以善用 `%` >2. 如果是上一個的斜線 (i - 1, j - 1) 可以善用 for 的初始化 ## 8/22 ### [392. Is Subsequence](https://leetcode.com/problems/is-subsequence/description/?source=submission-noac) <font color="#46c6c2">**Easy**</font> ==Topics== : `Two Pointers` `String` `Dynamic Programming` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(1)$ ```cpp class Solution { public: bool isSubsequence(string s, string t) { if (s == "") return true; int checkIndex = 0; for (int i = 0; i < t.length(); i++) { if (t[i] == s[checkIndex]) checkIndex++; if (checkIndex == s.length()) return true; } return false; } }; ``` ### [115. Distinct Subsequences](https://leetcode.com/problems/distinct-subsequences/description/?source=submission-noac) **review** <font color="#f8615c">**Hard**</font> ==Topics== : `String` `Dynamic Programming` #### Writing Method 1 (2D) * <font color="#2DB55D">**AC** (26ms) | **Beats** 73.18%</font> * $Time: O(n \times m)$ * $Space: O(n \times m)$ ```cpp class Solution { public: int numDistinct(string s, string t) { vector<vector<uint64_t>> dp(s.length() + 1, vector<uint64_t>(t.length() + 1, 0)); dp[0][0] = 1; for (int i = 1; i <= s.length(); i++) { dp[i][0] = 1; } for (int i = 1; i <= s.length(); i++) { for (int j = 1; j <= t.length(); j++) { if (s[i - 1] == t[j - 1]) dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]; else dp[i][j] = dp[i - 1][j]; } } return dp[s.length()][t.length()]; } }; ``` #### Writing Method 2 (1D) * <font color="#2DB55D">**AC** (7ms) | **Beats** 97.00%</font> * $Time: O(n \times m)$ * $Space: O(1)$ ```cpp class Solution { public: int numDistinct(string s, string t) { vector<uint64_t> dp(t.length() + 1, 0); dp[0] = 1; for (int i = 1; i <= s.length(); i++) { for (int j = t.length(); j > 0; j--) { if (s[i - 1] == t[j - 1]) dp[j] = dp[j - 1] + dp[j]; } } return dp[t.length()]; } }; ``` ## 8/23 ### [583. Delete Operation for Two Strings](https://leetcode.com/problems/delete-operation-for-two-strings/description/?source=submission-noac) <font color="#fac31d">**Medium**</font> ==Topics== : `String` `Dynamic Programming` #### Writing Method 1 (2D) * <font color="#2DB55D">**AC** (13ms) | **Beats** 44.21%</font> * $Time: O(n \times m)$ * $Space: O(n \times m)$ ```cpp class Solution { public: int minDistance(string word1, string word2) { vector<vector<int>> dp(word1.length() + 1, vector<int>(word2.length() + 1, 0)); for (int i = 1; i <= word1.length(); i++) { dp[i][0] = i; } for (int i = 1; i <= word2.length(); i++) { dp[0][i] = i; } for (int i = 1; i <= word1.length(); i++) { for (int j = 1; j <= word2.length(); j++) { if (word1[i - 1] == word2[j - 1]) dp[i][j] = dp[i - 1][j - 1]; else dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1; } } return dp[word1.length()][word2.length()]; } }; ``` #### Writing Method 2 (1D) * <font color="#2DB55D">**AC** (3ms) | **Beats** 97.92%</font> * $Time: O(n \times m)$ * $Space: O(m)$ --- >[!Warning] 錯誤初始化 ```cpp= public: int minDistance(string word1, string word2) { vector<int> dp(word2.length() + 1); for (int i = 0; i <= word2.length(); i++) { dp[i] = i; } for (int i = 1, prev = 0; i <= word1.length(); prev = i++) { for (int j = 1; j <= word2.length(); j++) { int cur = dp[j]; if (word1[i - 1] == word2[j - 1]) dp[j] = prev; else dp[j] = min(dp[j - 1], dp[j]) + 1; prev = cur; } } return dp[word2.length()]; } }; ``` ```diff +8 dp[0] = i ``` --- ```cpp class Solution { public: int minDistance(string word1, string word2) { vector<int> dp(word2.length() + 1); for (int i = 0; i <= word2.length(); i++) { dp[i] = i; } for (int i = 1, prev = 0; i <= word1.length(); prev = i++) { dp[0] = i; for (int j = 1; j <= word2.length(); j++) { int cur = dp[j]; if (word1[i - 1] == word2[j - 1]) dp[j] = prev; else dp[j] = min(dp[j - 1], dp[j]) + 1; prev = cur; } } return dp[word2.length()]; } }; ``` ## 8/26 weekly contest ## 8/27 weekly contest ## 8/28 ### [496. Next Greater Element I](https://leetcode.com/problems/next-greater-element-i/description/) <font color="#46c6c2">**Easy**</font> ==Topics== : `Array` `Hash Table` `Stack` `Monotonic Stack` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(nums1.size() + nums2.size())$ * $Space: O(nums1.size())$ ```cpp class Solution { public: vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) { vector<int> ans(nums1.size()); unordered_map<int, int> map; stack<int> st; for (int i = 0; i < nums2.size(); i++) { while (!st.empty() && st.top() < nums2[i]) { map[st.top()] = nums2[i]; st.pop(); } st.push(nums2[i]); } while (!st.empty()) { map[st.top()] = -1; st.pop(); } for (int i = 0; i < nums1.size(); i++) { ans[i] = map[nums1[i]]; } return ans; } }; ``` ### [503. Next Greater Element II](https://leetcode.com/problems/next-greater-element-ii/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Stack` `Monotonic Stack` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(n)$ ```cpp class Solution { public: vector<int> nextGreaterElements(vector<int>& nums) { stack<int> st; vector<int> ans(nums.size(), -1); for (int i = 0; i < nums.size(); i++) { while (!st.empty() && nums[st.top()] < nums[i]) { ans[st.top()] = nums[i]; st.pop(); } st.push(i); } for (int i = 0; i < nums.size(); i++) { if (st.size() == 1) break; while (nums[st.top()] < nums[i]) { ans[st.top()] = nums[i]; st.pop(); } } return ans; } }; ``` ## 8/30 ### [797. All Paths From Source to Target](https://leetcode.com/problems/all-paths-from-source-to-target/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Backtracking` `Depth-First Search` `Breadth-First Search` `Graph` `Weekly Contest 75` * <font color="#2DB55D">**AC** (3ms) | **Beats** 76.02%</font> * $Time: O(2^n)$ * $Space: O(n)$ ```cpp class Solution { public: vector<vector<int>> ans; vector<int> ans_element; vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) { ans_element.push_back(0); dfs(graph, 0, graph.size() - 1); return ans; } void dfs(vector<vector<int>>& graph, int node, int last_node) { if (node == last_node) { ans.push_back(ans_element); return; } for (int i = 0; i < graph[node].size(); i++) { ans_element.push_back(graph[node][i]); dfs(graph, graph[node][i], last_node); ans_element.pop_back(); } return; } }; ``` ## 9/4 ### [200. Number of Islands](https://leetcode.com/problems/number-of-islands/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Depth-First Search` `Breadth-First Search` `Union Find` `Matrix` #### Writing Method 1 (DFS) * <font color="#2DB55D">**AC** (30ms) | **Beats** 37.16%</font> * $Time: O(m \times n)$ * $Space: O(m \times n)$ ```cpp class Solution { public: int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; void dfs(vector<vector<char>>& grid, int row, int col) { for (int i = 0; i < 4; i++) { int next_row = row + dir[i][0]; int next_col = col + dir[i][1]; if (next_row < 0 || next_row >= grid.size() || next_col < 0 || next_col >= grid[0].size()) continue; if (grid[next_row][next_col] != '0') { grid[next_row][next_col] = '0'; dfs(grid, next_row, next_col); } } } int numIslands(vector<vector<char>>& grid) { int ans = 0; for (int i = 0; i < grid.size(); i++) { for (int j = 0; j < grid[0].size(); j++) { if (grid[i][j] != '0') { ans++; dfs(grid, i, j); } } } return ans; } }; ``` #### Writing Method 2 (bfs) * <font color="#2DB55D">**AC** (26ms) | **Beats** 64.75%</font> * $Time: O(m \times n)$ * $Space: O(m \times n)$ ```cpp class Solution { public: int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; void bfs(vector<vector<char>>& grid, int row, int col) { queue<pair<int, int>> que; grid[row][col] = '0'; que.push({row, col}); while (!que.empty()) { pair<int, int> cur = que.front(); que.pop(); row = cur.first; col = cur.second; for (int i = 0; i < 4; i++) { int next_row = row + dir[i][0]; int next_col = col + dir[i][1]; if (next_row < 0 || next_row >= grid.size() || next_col < 0 || next_col >= grid[0].size()) continue; if (grid[next_row][next_col] != '0') { grid[next_row][next_col] = '0'; que.push({next_row, next_col}); } } } } int numIslands(vector<vector<char>>& grid) { int ans = 0; for (int i = 0; i < grid.size(); i++) { for (int j = 0; j < grid[0].size(); j++) { if (grid[i][j] != '0') { ans++; bfs(grid, i, j); } } } return ans; } }; ``` ### [695. Max Area of Island](https://leetcode.com/problems/max-area-of-island/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Depth-First Search` `Breadth-First Search` `Union Find` `Matrix` * <font color="#2DB55D">**AC** (1ms) | **Beats** 66.30%</font> * $Time: O(m \times n)$ * $Space: O(m \times n)$ ```cpp class Solution { public: int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; int bfs(vector<vector<int>>& grid, int row, int col) { int area = 0; queue<pair<int, int>> que; que.push({row, col}); area++; grid[row][col] = 0; while (!que.empty()) { int row = que.front().first; int col = que.front().second; que.pop(); for (int i = 0; i < 4; i++) { int next_row = row + dir[i][0]; int next_col = col + dir[i][1]; if (next_row < 0 || next_row >= grid.size() || next_col < 0 || next_col >= grid[0].size()) continue; if (grid[next_row][next_col] == 1) { que.push({next_row, next_col}); area++; grid[next_row][next_col] = 0; } } } return area; } int maxAreaOfIsland(vector<vector<int>>& grid) { int ans = 0; for (int i = 0; i < grid.size(); i++) { for (int j = 0; j < grid[0].size(); j++) { if (grid[i][j] == 1) { ans = max(ans, bfs(grid, i, j)); } } } return ans; } }; ``` ### [1254. Number of Closed Islands](https://leetcode.com/problems/number-of-closed-islands/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Depth-First Search` `Breadth-First Search` `Union Find` `Matrix` `Weekly Contest 162` * <font color="#2DB55D">**AC** (2ms) | **Beats** 51.90%</font> * $Time: O(m \times n)$ * $Space: O(m \times n)$ ```cpp class Solution { public: int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; void bfs(vector<vector<int>>& grid, int row, int col) { queue<pair<int, int>> que; que.push({row, col}); grid[row][col] = 1; while (!que.empty()) { int row = que.front().first; int col = que.front().second; que.pop(); for (int i = 0; i < 4; i++) { int next_row = row + dir[i][0]; int next_col = col + dir[i][1]; if (next_row < 0 || next_row >= grid.size() || next_col < 0 || next_col >= grid[0].size()) continue; if (grid[next_row][next_col] == 0) { que.push({next_row, next_col}); grid[next_row][next_col] = 1; } } } } int closedIsland(vector<vector<int>>& grid) { int cnt = 0; for (int i = 0; i < grid.size(); i++) { if (grid[i][0] == 0) bfs(grid, i, 0); if (grid[i][grid[0].size() - 1] == 0) bfs(grid, i, grid[0].size() - 1); } for (int i = 0; i < grid[0].size(); i++) { if (grid[0][i] == 0) bfs(grid, 0, i); if (grid[grid.size() - 1][i] == 0) bfs(grid, grid.size() - 1, i); } for (int i = 0; i < grid.size(); i++) { for (int j = 0; j < grid[0].size(); j++) { if (grid[i][j] == 0) { cnt++; bfs(grid, i, j); } } } return cnt; } }; ``` ## 9/5 ### [1254. Number of Closed Islands](https://leetcode.com/problems/number-of-closed-islands/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Depth-First Search` `Breadth-First Search` `Union Find` `Matrix` `Weekly Contest 162` * <font color="#2DB55D">Time Limit Exceeded</font> * $Time: O(m^2 \times n^2)$ * $Space: O(m \times n)$ ```cpp class Solution { public: vector<vector<int>> ans; int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; bool bfs(vector<vector<int>>& heights, vector<vector<int>>& reach_both, int row, int col) { bool reach_pacific = false, reach_atlantic = false; queue<pair<int, int>> que; que.push({row, col}); while (!que.empty()) { row = que.front().first; col = que.front().second; que.pop(); for (int i = 0; i < 4; i++) { int next_row = row + dir[i][0]; int next_col = col + dir[i][1]; if (next_row < 0 || next_col < 0) { reach_pacific = true; } else if (next_row >= heights.size() || next_col >= heights[0].size()) { reach_atlantic = true; } else if (heights[next_row][next_col] > heights[row][col]) { continue; } else if (reach_both[next_row][next_col] == 1) { return true; } else { que.push({next_row, next_col}); } if (reach_pacific && reach_atlantic) return true; } } return false; } vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) { vector<vector<int>> reach_both(heights.size(), vector<int>(heights[0].size(), 0)); for (int i = 0; i < heights.size(); i++) { for (int j = 0; j < heights[0].size(); j++) { if (bfs(heights, reach_both, i, j)) { reach_both[i][j] = 1; ans.push_back({i, j}); } else { reach_both[i][j] = -1; } } } return ans; } }; ``` * <font color="#2DB55D">**AC** (15ms) | **Beats** 30.07%</font> * $Time: O(m \times n)$ * $Space: O(m \times n)$ ```cpp class Solution { public: int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; void bfs(vector<vector<int>>& heights, vector<vector<bool>>& visited, int row, int col) { if (visited[row][col]) return; queue<pair<int, int>> que; visited[row][col] = true; que.push({row, col}); while (!que.empty()) { row = que.front().first; col = que.front().second; que.pop(); for (int i = 0; i < 4; i++) { int next_row = row + dir[i][0]; int next_col = col + dir[i][1]; if (next_row < 0 || next_row >= heights.size() || next_col < 0 || next_col >= heights[0].size()) continue; if (visited[next_row][next_col] || heights[next_row][next_col] < heights[row][col]) continue; visited[next_row][next_col] = true; que.push({next_row, next_col}); } } } vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) { vector<vector<int>> ans; vector<vector<bool>> reach_pacific(heights.size(), vector<bool>(heights[0].size(), false)); vector<vector<bool>> reach_atlantic(heights.size(), vector<bool>(heights[0].size(), false)); for (int i = 0; i < heights.size(); i++) { bfs(heights, reach_pacific, i, 0); bfs(heights, reach_atlantic, i, heights[0].size() - 1); } for (int i = 0; i < heights[0].size(); i++) { bfs(heights, reach_pacific, 0, i); bfs(heights, reach_atlantic, heights.size() - 1, i); } for (int i = 0; i < heights.size(); i++) { for (int j = 0; j < heights[0].size(); j++) { if (reach_pacific[i][j] && reach_atlantic[i][j]) ans.push_back({i, j}); } } return ans; } }; ``` ## 9/6 ### [Q3. Maximum Product of Two Integers With No Common Bits](https://leetcode.com/contest/weekly-contest-465/problems/maximum-product-of-two-integers-with-no-common-bits/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Weekly Contest 465` * <font color="#2DB55D">Time Limit Exceeded</font> * $Time: O(n^2)$ * $Space: O(1)$ ```cpp class Solution { public: long long maxProduct(vector<int>& nums) { sort(nums.begin(), nums.end(), greater<int>()); long long ans = 0; for (int i = 0; i < nums.size() - 1; i++) { if ((long long) nums[i] * nums[i] <= ans) break; for (int j = i + 1; j < nums.size(); j++) { if ((nums[i] & nums[j]) != 0) continue; long long product = (long long) nums[i] * nums[j]; if (product <= ans) break; ans = max(ans, product); } } return ans; } }; ``` * <font color="#2DB55D">**AC** (419ms)</font> * $Time: O(m \times 2 ^ m)$ * $Space: O(2 ^ m)$ ```cpp class Solution { public: long long maxProduct(vector<int>& nums) { long long ans = 0; int num_bits = 0, max_num = *max_element(nums.begin(), nums.end()); while ((1 << num_bits) <= max_num) num_bits++; vector<int> dp(1 << num_bits, 0); for (int i: nums) { dp[i] = i; } for (int i = 0; i < num_bits; i++) { for (int mask = 0; mask < (1 << num_bits); mask++) { if (mask & (1 << i)) { dp[mask] = max(dp[mask], dp[mask ^ (1 << i)]); } } } for (int i: nums) { int complement = ((1 << num_bits) - 1) ^ i; ans = max(ans, 1LL * dp[i] * dp[complement]); } return ans; } }; ``` ## 9/7 ### [827. Making A Large Island](https://leetcode.com/problems/making-a-large-island/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Depth-First Search` `Breadth-First Search` `Union Find` `Matrix` `Weekly Contest 82` * <font color="#2DB55D">Time Limit Exceeded</font> * $Time: O(n^2)$ * $Space: O(1)$ ```cpp class Solution { public: int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; int bfs(vector<vector<int>>& grid, int row, int col) { int area = 0; vector<vector<bool>> visited(grid.size(), vector<bool>(grid[0].size(), false)); queue<pair<int, int>> que; que.push({row, col}); visited[row][col] = true; area++; while (!que.empty()) { row = que.front().first; col = que.front().second; que.pop(); for (int i = 0; i < 4; i++) { int next_row = row + dir[i][0]; int next_col = col + dir[i][1]; if (next_row < 0 || next_row >= grid.size() || next_col < 0 || next_col >= grid[0].size()) continue; if (grid[next_row][next_col] == 0 || visited[next_row][next_col]) continue; que.push({next_row, next_col}); visited[next_row][next_col] = true; area++; } } return area; } int largestIsland(vector<vector<int>>& grid) { int ans = 0; for (int i = 0; i < grid.size(); i++) { for (int j = 0; j < grid[0].size(); j++) { ans = max(ans, bfs(grid, i, j)); } } return ans; } }; ``` * <font color="#2DB55D">**AC** (20ms) | **Beats** 40.98%</font> * $Time: O(m \times n)$ * $Space: O(m \times n)$ ```cpp class Solution { public: vector<int> island_area; int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; int bfs(vector<vector<int>>& grid, int id, int row, int col) { int area = 0; queue<pair<int, int>> que; que.push({row, col}); area++; grid[row][col] = id; while (!que.empty()) { row = que.front().first; col = que.front().second; que.pop(); for (int i = 0; i < 4; i++) { int next_row = row + dir[i][0]; int next_col = col + dir[i][1]; if (next_row < 0 || next_row >= grid.size() || next_col < 0 || next_col >= grid[0].size()) continue; if (grid[next_row][next_col] != 1) continue; que.push({next_row, next_col}); area++; grid[next_row][next_col] = id; } } island_area.push_back(area); return area; } int largestIsland(vector<vector<int>>& grid) { island_area.push_back(0); island_area.push_back(0); int id = 2, ans = 0; for (int i = 0; i < grid.size(); i++) { for (int j = 0; j < grid[0].size(); j++) { if (grid[i][j] == 1) { ans = max(ans, bfs(grid, id, i, j)); id++; } } } for (int i = 0; i < grid.size(); i++) { for (int j = 0; j < grid[0].size(); j++) { if (grid[i][j] != 0) continue; unordered_set<int> uset; int cur_area = 1; for (int k = 0; k < 4; k++) { int next_i = i + dir[k][0]; int next_j = j + dir[k][1]; if (next_i < 0 || next_i >= grid.size() || next_j < 0 || next_j >=grid[0].size()) continue; if (grid[next_i][next_j] == 0) continue; uset.insert(grid[next_i][next_j]); } for (const auto& s: uset) { cur_area += island_area[s]; } ans = max(ans, cur_area); } } return ans; } }; ``` ## 9/9 ### [463. Island Perimeter](https://leetcode.com/problems/island-perimeter/description/) <font color="#46c6c2">**Easy**</font> ==Topics== : `Array` `Depth-First Search` `Breadth-First Search` `Matrix` * <font color="#2DB55D">**AC** (3ms) | **Beats** 70.95%</font> * $Time: O(m \times n)$ * $Space: O(1)$ ```cpp class Solution { public: int islandPerimeter(vector<vector<int>>& grid) { int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; int ans = 0; for (int i = 0; i < grid.size(); i++) { for (int j = 0; j < grid[0].size(); j++) { if (grid[i][j] == 0) continue; for (int k = 0; k < 4; k++) { int next_i = i + dir[k][0]; int next_j = j + dir[k][1]; if (next_i < 0 || next_i >= grid.size() || next_j < 0 || next_j >= grid[0].size()) { ans++; continue; } if (grid[next_i][next_j] == 0) ans++; } } } return ans; } }; ``` ## 9/10 ### [127. Word Ladder](https://leetcode.com/problems/word-ladder/description/) <font color="#f8615c">**Hard**</font> ==Topics== : `Hash Table` `String` `Breadth-First Search` * <font color="#2DB55D">**AC** (99ms) | **Beats** 44.64%</font> * $Time: O(m \times n \times 26)$ * $Space: O(m)$ >m: number of edges >n: the length of beginWord and endWord ```cpp class Solution { public: int ladderLength(string beginWord, string endWord, vector<string>& wordList) { unordered_set<string> uset(wordList.begin(), wordList.end()); unordered_map<string, int> umap; umap[beginWord] = 1; queue<string> que; que.push(beginWord); while (!que.empty()) { string cur = que.front(); int cur_path = umap[cur]; que.pop(); if (cur == endWord) return cur_path; for (int i = 0; i < cur.length(); i++) { for (char j = 'a'; j <= 'z'; j++) { if (j == cur[i]) continue; string tmp = cur; tmp[i] = j; if (uset.find(tmp) == uset.end() || umap.find(tmp) != umap.end()) continue; umap[tmp] = cur_path + 1; que.push(tmp); } } } return 0; } }; ``` ### [1557. Minimum Number of Vertices to Reach All Nodes](https://leetcode.com/problems/minimum-number-of-vertices-to-reach-all-nodes/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Graph` `Biweekly Contest 33` * <font color="#2DB55D">**AC** (3ms) | **Beats** 78.12%</font> * $Time: O(n + e)$ * $Space: O(n)$ ```cpp class Solution { public: vector<int> findSmallestSetOfVertices(int n, vector<vector<int>>& edges) { vector<int> edge_node(n, 0); vector<int> ans; for (int i = 0; i < edges.size(); i++) { edge_node[edges[i][1]] = 1; } for (int i = 0; i < n; i++) { if (edge_node[i] == 0) ans.push_back(i); } return ans; } }; ``` ## 9/11 ### [Learning Union Find](https://gitee.com/programmercarl/leetcode-master/blob/master/problems/kamacoder/%E5%9B%BE%E8%AE%BA%E5%B9%B6%E6%9F%A5%E9%9B%86%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.md) ```cpp #include <bits/stdc++.h> #define N 10 using namespace std; vector<int> father(N); void fatherInit(vector<int>& father) { for (int i = 0; i < father.size(); i++) { father[i] = i; } } int findFather(vector<int>& father, int a) { return (a == father[a]) ? a : father[a] = findFather(father, father[a]); } bool fatherIsSame(vector<int>& father, int a, int b) { return findFather(father, a) == findFather(father, b); } void join(vector<int>& father, int a, int b) { int v = findFather(father, a); int u = findFather(father, b); if (v == u) return; father[u] = v; } void printNode(vector<int>& node) { for (int i = 0; i < node.size(); i++) { cout << i << "-->" << node[i] << endl; } } int main() { // initialize fatherInit(father); // chose optino int option, a, b; while (true) { cout << "1. print father \n2. join node \n3. in the same union \n4. exit" << endl; cin >> option; switch (option) { case 1: printNode(father); break; case 2: cin >> a >> b; join(father, a, b); cout << "finished join" << endl; break; case 3: cin >> a >> b; if (fatherIsSame(father, a, b)) { cout << a << " and " << b << " in the same union" << endl; } else { cout << a << " and " << b << " in the different union" << endl; } break; default: break; } if (option == 4) break; cout << endl << "==============================" << endl; } return 0; } ``` ## 9/12 ### [1971. Find if Path Exists in Graph](https://leetcode.com/problems/find-if-path-exists-in-graph/description/) <font color="#46c6c2">**Easy**</font> ==Topics== : `Depth-First Search` `Breadth-First Search` `Union Find` `Graph` * <font color="#2DB55D">**AC** (27ms) | **Beats** 94.94%</font> * $Time: O(n)$ * $Space: O(n)$ ```cpp class Solution { public: int findFather(vector<int>& father, int a) { return (father[a] == a) ? a : father[a] = findFather(father, father[a]); } bool isSame(vector<int>& father, int a, int b) { return findFather(father, a) == findFather(father, b); } void join(vector<int>& father, int a, int b) { int v = findFather(father, a); int u = findFather(father, b); if (v != u) father[v] = u; } bool validPath(int n, vector<vector<int>>& edges, int source, int destination) { vector<int> father(n); // initialize for (int i = 0; i < n; i++) { father[i] = i; } for (int i = 0; i < edges.size(); i++) { join(father, edges[i][0], edges[i][1]); } return isSame(father, source, destination); } }; ``` ### [684. Redundant Connection](https://leetcode.com/problems/redundant-connection/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Depth-First Search` `Breadth-First Search` `Union Find` `Graph` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(n)$ ```cpp class Solution { public: vector<int> father; int find(int a) { return (a == father[a]) ? a : father[a] = find(father[a]); } bool isSame(int a, int b) { return find(a) == find(b); } void join(int a, int b) { int v = find(a); int u = find(b); if (v != u) father[u] = v; } vector<int> findRedundantConnection(vector<vector<int>>& edges) { for (int i = 0; i <= edges.size(); i++) { father.push_back(i); } for (int i = 0; i < edges.size(); i++) { if (isSame(edges[i][0], edges[i][1])) return edges[i]; join(edges[i][0], edges[i][1]); } return {0, 0}; } }; ``` ### [685. Redundant Connection II](https://leetcode.com/problems/redundant-connection-ii/description/) <font color="#f8615c">**Hard**</font> ==Topics== : `Depth-First Search` `Breadth-First Search` `Union Find` `Graph` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ * $Space: O(n)$ >[!Note] 思考三種 case >case 1: 兩個入沒有環 >case 2: 兩個入有環 >case 3: 都只有一個入,直接判斷環 ```cpp class Solution { public: vector<int> father; int find(int a) { return (a == father[a]) ? a : father[a] = find(father[a]); } bool isSame(int a, int b) { return find(a) == find(b); } void join(int a, int b) { int v = find(a); int u = find(b); if (v != u) father[u] = v; } bool isTreeAfterRemoved(vector<vector<int>>& edges, vector<int>& deleteEdge) { for (int i = 0; i < edges.size(); i++) { if (edges[i][0] == deleteEdge[0] && edges[i][1] == deleteEdge[1]) continue; if (isSame(edges[i][0], edges[i][1])) return false; join(edges[i][0], edges[i][1]); } return true; } vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) { vector<int> ans1, ans2; vector<int> node_in(edges.size() + 1, 0); for (int i = 0; i <= edges.size(); i++) { father.push_back(i); } for (int i = 0; i < edges.size(); i++) { if (node_in[edges[i][1]] != 0) { ans1 = {node_in[edges[i][1]], edges[i][1]}; ans2 = edges[i]; break; } node_in[edges[i][1]] = edges[i][0]; } if (ans1.size() == 2) { if (isTreeAfterRemoved(edges, ans2)) return ans2; return ans1; } for (int i = 0; i < edges.size(); i++) { if (isSame(edges[i][0], edges[i][1])) return edges[i]; join(edges[i][0], edges[i][1]); } return {0, 0}; } }; ``` ## 9/13 ### [1584. Min Cost to Connect All Points](https://leetcode.com/problems/min-cost-to-connect-all-points/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Array` `Union Find` `Graph` `Minimum Spanning Tree` `Weekly Contest 206` #### Writing Method 1 (prim) * <font color="#2DB55D">**AC** (15ms) | **Beats** 98.14%</font> * $Time: O(n ^ 2)$ n is the number of nodes * $Space: O(n)$ >[!Note] prim 算法找 mini spinning tree >1. find nearest point >2. join the point >3. update the min distance of tree ```cpp class Solution { public: int countDist(int x1, int y1, int x2, int y2) { return abs(x1 - x2) + abs(y1 - y2); } int minCostConnectPoints(vector<vector<int>>& points) { int ans = -INT_MAX; vector<int> minDist(points.size(), INT_MAX); vector<int> isVisit(points.size(), false); for (int i = 0; i < points.size(); i++) { int cur = 0; int dist = minDist[0]; for (int i = 1; i < points.size(); i++) { if (!isVisit[i] && minDist[i] < dist) { dist = minDist[i]; cur = i; } } isVisit[cur] = true; ans += minDist[cur]; for (int i = 1; i < points.size(); i++) { if (!isVisit[i]) { minDist[i] = min(minDist[i], countDist(points[cur][0], points[cur][1], points[i][0], points[i][1])); } } } return ans; } }; ``` #### Writing Method 2 (Kruskal) * <font color="#2DB55D">**AC** (286ms) | **Beats** 56.91%</font> * $Time: O(n \times log(n))$ n is the number of edges. * $Space: O(n)$ >[!Note] Kruskal >1. sort every edges >2. union find ```cpp class Solution { public: vector<int> father; struct Edge { int l, r, val; }; int dist(vector<int>& v1, vector<int>& v2) { return abs(v1[0] - v2[0]) + abs(v1[1] - v2[1]); } int find(int a) { return (a == father[a]) ? a : father[a] = find(father[a]); } bool isSame(int a, int b) { return find(a) == find(b); } void join(int a, int b) { int v = find(a); int u = find(b); if (v != u) father[u] = v; } int minCostConnectPoints(vector<vector<int>>& points) { vector<Edge> edges; int ans = 0; for (int i = 0; i < points.size(); i++) { father.push_back(i); for (int j = i + 1; j < points.size(); j++) { edges.push_back({i, j, dist(points[i], points[j])}); } } sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) { return a.val < b.val; }); for (int i = 0; i < edges.size(); i++) { if (isSame(edges[i].l, edges[i]. r)) continue; join(edges[i].l, edges[i].r); ans += edges[i].val; } return ans; } }; ``` ## 9/16 ### [662. Maximum Width of Binary Tree](https://leetcode.com/problems/maximum-width-of-binary-tree/description/) <font color="#fac31d">**Medium**</font> ==Topics== : `Tree` `Depth-First Search` `Breadth-First Search` `Binary Tree` * <font color="#2DB55D">**AC** (0ms) | **Beats** 100%</font> * $Time: O(n)$ n is the number of nodes * $Space: O(n)$ ```cpp /** * 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: int widthOfBinaryTree(TreeNode* root) { int ans = 1; int previous_width = 1; bool count_width = false; queue<pair<uint64_t, TreeNode*>> que; que.push({1, root}); while (!que.empty()) { int size = que.size(); uint64_t right = que.front().first; uint64_t left = right; for (int i = 0; i < size; i++) { uint64_t cur_width = que.front().first; TreeNode* cur_node = que.front().second; que.pop(); left = cur_width; if (cur_node->right != nullptr) { que.push({2 * cur_width, cur_node->right}); } if (cur_node->left != nullptr) { que.push({2 * cur_width - 1, cur_node->left}); } } ans = max(ans, (int) (right - left) + 1); } return ans; } }; ```