今後的刷題筆記都不再單獨放置了,全部放在一起,節省空間
每道題後標註的日期均爲上傳日期,不是完成日期
ps:文件太大了,格式化很麻烦,所以还是分开吧
Easy [202] 快乐数 hash-table | math
2022/03/02
class Solution { public : bool isHappy (int n) { if (n == 1 ) { return 1 ; } if (n > 1 && n <= 4 ) { return 0 ; } int num = 0 ; while (n) { num += (n % 10 ) * (n % 10 ); n /= 10 ; } return isHappy (num); } };
[94] 二叉树的中序遍历 hash-table | stack | tree
2022/03/07
关于迭代:迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程
关于 STL - emplace 与 push 的区别:
设置数据结构 data
//假设栈内的数据类型是data
class data {
int a;
int b;
public:
data(int x, int y):a(x), b(y) {}
};
push 的操作可以直接用于 emplace
//push
data d(1,2);
S.push(d) 或 S.emplace(d);
在传入时候构造对象
S.push(data(1,2));
S.emplace(data(1,2));
emplace 可以直接传入构造对象需要的元素,然后自己调用其构造函数!
S.emplace(1,2)
意思是,emplace 这样接受新对象的时候,自己会调用其构造函数生成对象然后放在容器内(比如这里传入了 1,2,它则会自动调用一次 data(1,2))
而 push,只能让其构造函数构造好了对象之后,再使用复制构造函数!
相当于 emplace 直接把原料拿进家,造了一个。而 push 是造好了之后,再复制到自己家里,多了复制这一步。
所以 emplace 相对于 push,使用第三种方法会更节省内存。
注意 :
emplace_back(type) 对应 push_back(type)
emplace(i, type) 对应于 insert(type, i)
emplace_front(type) 对应于 push_front()
但是 !对于 stack 和 queue,只有 push 操作,所以也只有 emplace 操作,此时它们是相对应的。
class Solution { public : vector<int > inorderTraversal (TreeNode *root) { stack<TreeNode *> treeNodeStack; vector<int > ans; while (root || !treeNodeStack.empty ()) { while (root) { treeNodeStack.push (root); root = root->left; } auto node = treeNodeStack.top (); treeNodeStack.pop (); ans.emplace_back (node->val); root = node->right; } return ans; } };
[101] 对称二叉树 tree | depth-first-search | breadth-first-search
2022/03/08
利用深搜解决
class Solution { private : bool function (TreeNode *leftRoot, TreeNode *rightRoot) { if (rightRoot && leftRoot) { if (rightRoot->val != leftRoot->val) return false ; else { return function (leftRoot->left, rightRoot->right) && function (leftRoot->right, rightRoot->left); } } else if (rightRoot || leftRoot) { return false ; } else { return true ; } } public : bool isSymmetric (TreeNode *root) { return function (root->left, root->right); } };
[104] 二叉树的最大深度 tree | depth-first-search
2022/03/08
超级无敌螺旋托马斯火箭简单的递归
class Solution { private : int maxDeep = 0 ; void findMaxDeep (TreeNode *root, int deep) { if (!root) { maxDeep = max (maxDeep, deep); return ; } findMaxDeep (root->left, deep + 1 ); findMaxDeep (root->right, deep + 1 ); } public : int maxDepth (TreeNode *root) { findMaxDeep (root, 0 ); return maxDeep; } };
[160] 相交链表 linked-list
2022/03/13
class Solution { public : ListNode *getIntersectionNode (ListNode *headA, ListNode *headB) { vector<ListNode *> listA, listB; while (headA) { listA.emplace_back (headA); headA = headA->next; } while (headB) { listB.emplace_back (headB); headB = headB->next; } int posA = listA.size () - 1 , posB = listB.size () - 1 ; for (; posA >= 0 && posB >= 0 ; posA--, posB--) { if (listA[posA] != listB[posB]) { break ; } } return posA >= 0 ? listA[posA]->next : listA[0 ]; } };
[169] 多数元素 array | divide-and-conquer | bit-manipulation
2022/03/14
摩尔投票法 :
核心就是对拼消耗。
玩一个诸侯争霸的游戏,假设你方人口超过总人口一半以上,并且能保证每个人口出去干仗都能一对一同归于尽。最后还有人活下来的国家就是胜利。
那就大混战呗,最差所有人都联合起来对付你(对应你每次选择作为计数器的数都是众数),或者其他国家也会相互攻击(会选择其他数作为计数器的数),但是只要你们不要内斗,最后肯定你赢。
最后能剩下的必定是自己人。
class Solution { public : int majorityElement (vector<int >& nums) { int ans, count = 0 ; for (int i = 0 ; i < nums.size (); i++) { if (count == 0 ) { ans = nums[i]; count++; } else { count += nums[i] == ans ? 1 : -1 ; } } return ans; } };
Medium [201] 数字范围按位与 bit-manipulation
2022/03/02
_解法看註釋就行了,挺無語的_
class Solution { public : int rangeBitwiseAnd (int left, int right) { int i = 0 ; while (left < right) { left >>= 1 ; right >>= 1 ; i++; } return left << i; } };
[384] 打乱数组 Unknown (_不是我標錯 tag 了,那上面就是這個_)
2022/03/02
無語子,與其說是考驗算法,不如說是考驗隨機函數的用法
class Solution { private : vector<int > sample; public : Solution (vector<int >& nums) { sample = nums; } vector<int > reset () { return sample; } vector<int > shuffle () { vector<int > tmp = sample; vector<int > ans; int length = tmp.size (); for (int i = length; i > 0 ; i--) { int index = rand () % i; ans.push_back (tmp[index]); tmp.erase (tmp.begin () + index); } return ans; } };
[31] 下一个排列 array
2022/03/03
class Solution { public : void nextPermutation (vector<int >& nums) { for (int i = nums.size () - 2 ; i >= 0 ; i--) { if (nums[i] < nums[i + 1 ]) { int minPos = i + 1 ; for (int j = i + 1 ; j < nums.size (); j++) { minPos = nums[j] < nums[minPos] && nums[j] > nums[i] ? j : minPos; } swap (nums[i], nums[minPos]); sort (nums.begin () + i + 1 , nums.end ()); return ; } } sort (nums.begin (), nums.end ()); return ; } };
[48] 旋转图像 array
2022/03/04
class Solution { public : void rotate (vector<vector<int >> &matrix) { int n = matrix.size (); for (int i = 0 ; i < n; i++) { for (int j = i; j < n; j++) { swap (matrix[i][j], matrix[j][i]); } } for (int i = 0 ; i < n / 2 ; i++) { for (int j = 0 ; j < n; j++) { swap (matrix[j][i], matrix[j][n - 1 - i]); } } } };
[49] 字母异位词分组 hash-table | string
2022/03/04
存数字 double 是最大的!
class Solution { private : int getNum (char a) { switch (a) { case 'a' : return 2 ; case 'b' : return 3 ; case 'c' : return 5 ; case 'd' : return 7 ; case 'e' : return 11 ; case 'f' : return 13 ; case 'g' : return 17 ; case 'h' : return 19 ; case 'i' : return 23 ; case 'j' : return 29 ; case 'k' : return 31 ; case 'l' : return 37 ; case 'm' : return 41 ; case 'n' : return 43 ; case 'o' : return 47 ; case 'p' : return 53 ; case 'q' : return 59 ; case 'r' : return 61 ; case 's' : return 67 ; case 't' : return 71 ; case 'u' : return 73 ; case 'v' : return 79 ; case 'w' : return 83 ; case 'x' : return 89 ; case 'y' : return 97 ; case 'z' : return 101 ; } return 0 ; } public : vector<vector<string>> groupAnagrams (vector<string>& strs) { map<double , vector<string>> hashmap; for (auto i : strs) { double hashTmp = 1 ; for (auto chars : i) { hashTmp *= getNum (chars); } hashmap[hashTmp].push_back (i); } vector<vector<string>> ans; for (auto && i : hashmap) { ans.push_back (i.second); } return ans; } };
[56] 合并区间 array | sort
2022/03/04
双指针解法
class Solution { public : vector<vector<int >> merge (vector<vector<int >>& intervals) { vector<vector<int >> ans; vector<int > start (intervals.size()) , end (intervals.size()) ; for (int i = 0 ; i < intervals.size (); i++) { start[i] = intervals[i][0 ]; end[i] = intervals[i][1 ]; } sort (start.begin (), start.end ()); sort (end.begin (), end.end ()); for (int i = 0 , j = 0 ; i < intervals.size (); i++) { if (i == intervals.size () - 1 || start[i + 1 ] > end[i]) { ans.push_back ({start[j], end[i]}); j = i + 1 ; } } return ans; } };
[64] 最小路径和 array | dynamic-programming
2022/03/05
很简单的动规
class Solution { public : int minPathSum (vector<vector<int >>& grid) { vector<vector<int >> dp (grid.size (), vector <int >(grid[0 ].size ())); dp[0 ][0 ] = grid[0 ][0 ]; for (int i = 1 ; i < grid.size (); i++) { dp[i][0 ] = dp[i - 1 ][0 ] + grid[i][0 ]; } for (int i = 1 ; i < grid[0 ].size (); i++) { dp[0 ][i] = dp[0 ][i - 1 ] + grid[0 ][i]; } for (int i = 1 ; i < grid.size (); i++) { for (int j = 1 ; j < grid[0 ].size (); j++) { dp[i][j] = min (dp[i - 1 ][j], dp[i][j - 1 ]) + grid[i][j]; } } return dp.back ().back (); } };
[75] 颜色分类 array | two-pointers | sort
2022/03/05
题目不让用库函数里的 sort,那么就只好自己手撕了,应用到了双指针和分治的思想
class Solution { private : void qsort (vector<int >& nums, int begin, int end) { if (begin < end) { int left = begin; int right = end; int key = nums[right]; while (left < right) { while (left < right && nums[left] <= key) { left++; } if (left < right) { nums[right] = nums[left]; right--; } while (left < right && nums[right] >= key) { right--; } if (left < right) { nums[left] = nums[right]; left++; } } nums[right] = key; qsort (nums, begin, right - 1 ); qsort (nums, right + 1 , end); } } public : void sortColors (vector<int >& nums) { qsort (nums, 0 , nums.size () - 1 ); } };
[96] 不同的二叉搜索树 dynamic-programming | tree
2022/03/07
关于二叉查找树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树
很简单的题目,可以放到 easy 里面了
class Solution { public : int numTrees (int n) { vector<int > dp (n + 1 ) ; dp[0 ] = 1 ; dp[1 ] = 1 ; for (int i = 2 ; i <= n; i++) { for (int j = 1 ; j <= i; j++) { dp[i] += (dp[i - j] * dp[j - 1 ]); } } return dp.back (); } };
[98] 验证二叉搜索树 tree | depth-first-search
2022/03/07
class Solution { private : int left (TreeNode *root) { if (!root->left) return root->val; return left (root->left); } int right (TreeNode *root) { if (!root->right) return root->val; return right (root->right); } public : bool isValidBST (TreeNode *root) { bool ans = 1 ; if (root->left) { if (root->val <= right (root->left)) { return 0 ; } else ans = ans && isValidBST (root->left); } if (root->right) { if (root->val >= left (root->right)) { return 0 ; } else ans = ans && isValidBST (root->right); } return ans; } };
[102] 二叉树的层序遍历 tree | breadth-first-search
2022/03/08
很简单的广搜
class Solution { public : vector<vector<int >> levelOrder (TreeNode *root) { if (!root) return {}; vector<vector<int >> ans; deque<TreeNode *> bfs; bfs.emplace_back (root); while (!bfs.empty ()) { ans.emplace_back (0 ); int length = bfs.size (); while (length--) { auto tmp = bfs.front (); bfs.pop_front (); if (tmp->left) bfs.emplace_back (tmp->left); if (tmp->right) bfs.emplace_back (tmp->right); ans.back ().emplace_back (tmp->val); } } return ans; } };
[105] 从前序与中序遍历序列构造二叉树 array | tree | depth-first-search
2022/03/09
class Solution { private : TreeNode *function (vector<int > preorder, vector<int > inorder) { if (inorder.empty ()) return nullptr ; int rootPos = 0 ; for (; rootPos < inorder.size (); rootPos++) { if (inorder[rootPos] == preorder[0 ]) { break ; } } TreeNode *root = new TreeNode (preorder[0 ]); root->left = function ( vector <int >(preorder.begin () + 1 , preorder.begin () + rootPos + 1 ), vector <int >(inorder.begin (), inorder.begin () + rootPos)); root->right = function (vector <int >(preorder.begin () + rootPos + 1 , preorder.end ()), vector <int >(inorder.begin () + rootPos + 1 , inorder.end ())); return root; } public : TreeNode *buildTree (vector<int > &preorder, vector<int > &inorder) { return function (preorder, inorder); } };
[114] 二叉树展开为链表 tree | depth-first-search
2022/03/09
class Solution { public : void flatten (TreeNode *root) { if (!root) return ; flatten (root->left); flatten (root->right); auto tmp = root->right; root->right = root->left; root->left = nullptr ; while (root->right) root = root->right; root->right = tmp; } };
[128] 最长连续序列 array | union-find
2022/03/10
感觉照着 tag 用并查集还会更慢==
class Solution { private : public : int longestConsecutive (vector<int >& nums) { if (nums.empty ()) return 0 ; sort (nums.begin (), nums.end ()); int nowPath = 1 , maxPath = 1 ; for (int i = 1 ; i < nums.size (); i++) { if (nums[i] == nums[i - 1 ] + 1 ) { nowPath++; maxPath = max (maxPath, nowPath); } else if (nums[i] > nums[i - 1 ]) { nowPath = 1 ; maxPath = max (maxPath, nowPath); } } return maxPath; } };
[141] 环形链表 linked-list | two-pointers
2022/03/10
class Solution { public : bool hasCycle (ListNode *head) { if (!head) return false ; auto front = head, behind = head; while (front->next && front->next->next) { front = front->next; if (front == behind) return true ; front = front->next; if (front == behind) return true ; behind = behind->next; if (front == behind) return true ; } return false ; } };
[142] 环形链表 II linked-list | two-pointers
2022/03/12
class Solution { public : ListNode *detectCycle (ListNode *head) { if (!head) return NULL ; auto front = head, behind = head; int num = 10000 ; while (true ) { for (int i = 0 ; i < num; i++) { if (!front->next) return NULL ; front = front->next; if (front == behind) return behind; } behind = behind->next; } return NULL ; } };
[146] LRU 缓存 design
2022/03/12
利用指针或者迭代器来避免排序,虽然最后结果还是很慢但至少不超时了==
class LRUCache { private : map<int , list<pair<int , int >>::iterator> cache; list<pair<int , int >> hash; int cap; public : LRUCache (int capacity) { cap = capacity; } int get (int key) { if (cache.find (key) == cache.end ()) return -1 ; hash.push_front (*cache[key]); hash.erase (cache[key]); cache[key] = hash.begin (); return (*cache[key]).second; } void put (int key, int value) { if (cache.find (key) != cache.end ()) { hash.emplace_front (key, value); hash.erase (cache[key]); cache[key] = hash.begin (); } else { if (cache.size () >= cap) { cache.erase (hash.back ().first); hash.pop_back (); } hash.emplace_front (key, value); cache[key] = hash.begin (); } } };
[148] 排序链表 linked-list | sort
2022/03/13
class Solution { public : ListNode* sortList (ListNode* head) { if (!head) return nullptr ; vector<ListNode*> list; while (head) { list.emplace_back (head); head = head->next; } sort (list.begin (), list.end (), [](ListNode* a, ListNode* b) { return a->val < b->val; }); for (int i = 0 ; i < list.size () - 1 ; i++) { list[i]->next = list[i + 1 ]; } list.back ()->next = nullptr ; return list[0 ]; } };
[152] 乘积最大子数组 array | dynamic-programming
2022/03/13
class Solution { public : int maxProduct (vector<int >& nums) { vector<int > dpMax (nums.size(), 1 ) , dpMin (nums.size(), 1 ) ; dpMax[0 ] = nums[0 ]; dpMin[0 ] = nums[0 ]; int ans = nums[0 ]; for (int i = 1 ; i < nums.size (); i++) { dpMin[i] = min (nums[i], min (dpMin[i - 1 ] * nums[i], dpMax[i - 1 ] * nums[i])); dpMax[i] = max (nums[i], max (dpMin[i - 1 ] * nums[i], dpMax[i - 1 ] * nums[i])); ans = max (ans, dpMax[i]); } return ans; } };
[207] 课程表 depth-first-search | breadth-first-search | graph | topological-sort
2022/03/15
拓扑排序 :
方法是重复寻找一个入度为 0 的顶点,将该顶点从图中删除(即放进一个队列里存着,这个队列的顺序就是最后的拓扑排序,具体见程序),并将该结点及其所有的出边从图中删除(即该结点指向的结点的入度减 1),最终若图中全为入度为 1 的点,则这些点至少组成一个回路。
采用邻接矩阵存储时,遍历二维数组,求各顶点入度的时间复杂度是 O(n^2)。 遍历所有结点,找出入度为 0 的结点的时间复杂度是 O(n)。对于 n 个入度为 0 的结点,删除他们的出边的复杂度为 O(n^2)。 所以总的复杂度为 O(n^2)。
对于邻接表,遍历所有边,求各顶点入度的时间复杂度是 O(e),即边的个数。遍历所有结点,找出入度为 0 的结点的时间复杂度是 O(n),即顶点的个数。遍历所有边,删除入度为 0 的结点的出边的复杂度为 O(e),即边的个数。所以总的时间复杂度是 O(n+e)。
至于这道题我用了邻接矩阵的方法,感觉写起来简单
class Solution { public : bool canFinish (int numCourses, vector<vector<int >>& prerequisites) { vector<int > inDegree (numCourses) ; vector<vector<int >> edge (numCourses, vector <int >()); for (auto && i : prerequisites) { inDegree[i[1 ]]++; edge[i[0 ]].emplace_back (i[1 ]); } while (true ) { bool flag = false ; for (int i = 0 ; i < numCourses; i++) { if (inDegree[i] == 0 && !edge[i].empty ()) { while (!edge[i].empty ()) { inDegree[edge[i].back ()]--; edge[i].pop_back (); } flag = true ; break ; } } if (flag) { continue ; } else { break ; } } for (auto && i : inDegree) { if (i > 0 ) { return false ; } } return true ; } };
[215] 数组中的第 K 个最大元素 divide-and-conquer | heap
2022/03/15
不明白这题想干嘛==
class Solution { public : int findKthLargest (vector<int >& nums, int k) { sort (nums.begin (), nums.end ()); return nums[nums.size () - k]; } };
Hard [149] 直线上最多的点数 hash-table | math
2022/03/02
class Solution { public : int maxPoints (vector<vector<int >>& points) { if (points.size () <= 2 ) return points.size (); int Max = 2 ; for (int i = 0 ; i < points.size (); i++) { int same = 1 ; for (int j = i + 1 ; j < points.size (); j++) { int count = 0 ; if (points[i] == points[j]) { same++; } else { count++; long long xDiff = (long long )(points[i][0 ] - points[j][0 ]); long long yDiff = (long long )(points[i][1 ] - points[j][1 ]); for (int k = j + 1 ; k < points.size (); k++) if (xDiff * (points[i][1 ] - points[k][1 ]) == yDiff * (points[i][0 ] - points[k][0 ])) count++; } Max = max (Max, same + count); } if (Max > points.size () / 2 ) return Max; } return Max; } };
[10] 正则表达式匹配 string | dynamic-programming | backtracking
2022/03/02
一開始是從前向後判斷的,後來想想因爲*的緣故從後向前處理比較好,這裡運用了遞歸,效率上差動規很多
class Solution { public : bool isMatch (string s, string p) { int si = s.size () - 1 , pi = p.size () - 1 ; cout << s << " " << p << endl; while (pi >= 0 ) { if (p[pi] != '*' ) { if (si < 0 ) return 0 ; if (s[si] == p[pi] || p[pi] == '.' ) { si--; pi--; } else { return 0 ; } } else { string tmpP = p.substr (0 , pi - 1 ); string tmpS = s.substr (0 , si + 1 ); bool flag; int k = tmpS.size (); while ((flag = (!isMatch (tmpS, tmpP))) && k--) { tmpP = tmpP + p[pi - 1 ]; } return !flag; } } return si == pi; } };
[23] 合并 K 个升序链表 linked-list | divide-and-conquer | heap
2022/03/02
解釋一下 divide and conquer,字面意思分而治之,遞歸拆散數組,直到拆成一對或者一個,然後回溯處理
class Solution { private : ListNode *mergeTwoLists (ListNode *l1, ListNode *l2) { if (!l1) { return l2; } if (!l2) { return l1; } ListNode *l3; if (l1->val <= l2->val) { l3 = l1; l3->next = mergeTwoLists (l1->next, l2); } else { l3 = l2; l3->next = mergeTwoLists (l1, l2->next); } return l3; } public : ListNode *mergeKLists (vector<ListNode *> &lists) { if (lists.empty ()) return {}; else if (lists.size () == 1 ) return lists[0 ]; else if (lists.size () == 2 ) return mergeTwoLists (lists[0 ], lists[1 ]); vector<ListNode *> tmp; for (int i = 0 ; i < lists.size () / 2 ; i++) { tmp.push_back (lists.back ()); lists.pop_back (); } return mergeTwoLists (mergeKLists (lists), mergeKLists (tmp)); } };
[32] 最长有效括号 2022/03/03
string | dynamic-programming
用了好想的方法,不然的话时间和空间复杂度应该还可以压缩一倍
class Solution { public : int longestValidParentheses (string s) { if (s.empty ()) return 0 ; vector<int > pos (s.size(), -1 ) ; for (int i = 1 ; i < s.size (); i++) { if (s[i] == ')' ) { for (int j = i - 1 ; j >= 0 ; j--) { if (s[j] == '(' && pos[j] == -1 ) { pos[j] = i; pos[i] = j; break ; } } } } vector<int > length (s.size(), 0 ) ; length[0 ] = pos[0 ] == -1 ? 0 : 1 ; int Max = 0 ; for (int i = 1 ; i < s.size (); i++) { if (pos[i] != -1 ) { length[i] = length[i - 1 ] + 1 ; Max = max (Max, length[i]); } } return Max; } };
[42] 接雨水 2022/03/03
array | two-pointers | stack
标的是双指针,结果是靠着 DP 解的,牛 p 嗷
class Solution { public : int trap (vector<int >& height) { vector<int > left (height.size()) , right (height.size()) ; int ans = 0 ; for (int i = 1 ; i < height.size (); i++) { left[i] = max (left[i - 1 ], height[i - 1 ]); } for (int i = height.size () - 2 ; i >= 0 ; i--) { right[i] = max (right[i + 1 ], height[i + 1 ]); } for (int i = 0 ; i < height.size (); i++) { ans += max (0 , min (right[i], left[i]) - height[i]); } return ans; } };
[76] 最小覆盖子串 hash-table | two-pointers | string | sliding-window
2022/03/05
竟然是 hard,难以置信
class Solution { private : bool judge (vector<int >& hashS, vector<int >& hashT) { for (int i = 0 ; i < 58 ; i++) { if (hashT[i] > hashS[i]) { return 0 ; } } return 1 ; } public : string minWindow (string s, string t) { int left = 0 , right = -1 ; int Min = INT_MAX, minLeft = 0 , minRight = -1 ; vector<int > hashS (58 , 0 ) , hashT (58 , 0 ) ; for (auto i : t) { hashT[i - 'A' ]++; } while (true ) { if (!judge (hashS, hashT)) { if (right == s.size () - 1 ) break ; hashS[s[++right] - 'A' ]++; } else { if (right - left + 1 < Min) { Min = right - left + 1 ; minLeft = left; minRight = right; } hashS[s[left++] - 'A' ]--; } } return s.substr (minLeft, minRight - minLeft + 1 ); } };
[84] 柱状图中最大的矩形 array | stack
2022/03/06
本题的难点主要在于如何找到某一个柱子构成矩形而所需要延伸的最大程度,利用单调栈可以实现这一点
class Solution { public : int largestRectangleArea (vector<int >& heights) { heights.insert (heights.begin (), 0 ); heights.push_back (0 ); stack<int > indexStack; int area = 0 ; for (int i = 0 ; i < heights.size (); i++) { while (!indexStack.empty () && heights[i] < heights[indexStack.top ()]) { int height = heights[indexStack.top ()]; indexStack.pop (); area = max (area, (i - indexStack.top () - 1 ) * height); } indexStack.push (i); } return area; } };
[85] 最大矩形 array | hash-table | dynamic-programming | stack
2022/03/06
解法看注释
class Solution { private : int function (vector<int >& heights) { stack<int > indexStack; int area = 0 ; for (int i = 0 ; i < heights.size (); i++) { while (!indexStack.empty () && heights[i] < heights[indexStack.top ()]) { int height = heights[indexStack.top ()]; indexStack.pop (); area = max (area, (i - indexStack.top () - 1 ) * height); } indexStack.push (i); } return area; } public : int maximalRectangle (vector<vector<char >>& matrix) { int rows = matrix.size (), cols = matrix[0 ].size (); int area = 0 ; vector<int > heights (cols + 2 , 0 ) ; for (int i = 0 ; i < rows; i++) { for (int j = 0 ; j < cols; j++) { heights[j + 1 ] = matrix[i][j] == '0' ? 0 : heights[j + 1 ] + matrix[i][j] - '0' ; } area = max (area, function (heights)); } return area; } };
[124] 二叉树中的最大路径和 tree | depth-first-search
2022/03/10
class Solution { private : int function (TreeNode *root) { if (!root) return 0 ; return max (0 , root->val + max (function (root->left), function ((root->right)))); } public : int maxPathSum (TreeNode *root) { if (!root) return INT_MIN; return max (root->val + function (root->left) + function (root->right), max (maxPathSum (root->left), maxPathSum (root->right))); } };