├── chapter 5 ├── 75 颜色分类.cpp ├── 347 前K个高频元素.cpp ├── 215 数组中的第k个最大元素.cpp └── 451 根据字符出现的频率排序.cpp ├── chapter 14 ├── 1110 删点成林.cpp ├── 104 二叉树的最大深度.cpp ├── 226 翻转二叉树.cpp ├── 669 修剪二叉搜索树.cpp ├── 235 二叉搜索树的最近公共祖先.cpp ├── 101 对称二叉树.cpp ├── 530 二叉搜索树的最小绝对差.cpp ├── 617 合并二叉树.cpp ├── 538 把二叉搜索树转化为累加树.cpp ├── 897 递增顺序搜索树.cpp ├── 653 两数之和4-输入BST.cpp ├── 94 二叉树的中序遍历(迭代).cpp ├── 144 二叉树的前序遍历(迭代).cpp ├── 513 找树左下角的值.cpp ├── 236 二叉树的最近公共祖先.cpp ├── 437 路径总和3.cpp ├── 145 二叉树的后序遍历(迭代).cpp ├── 543 二叉树的直径.cpp ├── 105 从前序和中序遍历序列构造二叉树.cpp ├── 110 平衡二叉树.cpp ├── 889 根据前序和后序遍历序列构造二叉树.cpp ├── 572 另一棵树的子树.cpp ├── 637 二叉树的层平均值.cpp ├── 404 左叶子之和.cpp ├── 106 从中序与后序遍历序列构造二叉树.cpp ├── 109 将有序链表转化为二叉搜索树.cpp ├── 450 删除二叉搜索树中的节点.cpp ├── 208 实现前缀树(Trie).cpp └── 99 恢复二叉搜索树.cpp ├── chapter 2 ├── 135 分发糖果.cpp ├── 435 无重叠区间.cpp ├── 455 分发饼干.cpp ├── 605 种花问题.cpp ├── 665 非递减数列.cpp ├── 763 划分字母区间.cpp ├── 406 根据身高重建队列.cpp ├── 122 买股票的最佳时机2.cpp └── 452 用最少数量的箭引爆气球.cpp ├── chapter 3 ├── 142 环形链表2.cpp ├── 167 两数之和2.cpp ├── 633 平方数之和.cpp ├── 76 最小覆盖字串.cpp ├── 680 验证回文字符串.cpp ├── 88 合并两个有序数组.cpp └── 524 通过删除字母匹配到字典里最长单词.cpp ├── chapter 4 ├── 69 x的平方根.cpp ├── 4 寻找两个有序数组的中位数.cpp ├── 540 有序数组中的单一元素.cpp ├── 81 搜索旋转排序数组2.cpp ├── 154 寻找旋转排序数组中的最小值.cpp └── 34 在排序数组中查找元素的第一个和最后一个位置.cpp ├── chapter 10 ├── 342 4的幂.cpp ├── 693 交替位二进制数.cpp ├── 136 只出现一次的数字.cpp ├── 461 汉明距离.cpp ├── 476 数字的补数.cpp ├── 190 颠倒二进制位.cpp ├── 268 丢失的数.cpp ├── 338 比特位计数.cpp ├── 260 只出现一次的数字3.cpp └── 318 最大单词长度乘积.cpp ├── chapter 9 ├── 169 多数元素.cpp ├── 326 3的幂.cpp ├── 172 阶乘后的0.cpp ├── 504 7进制数.cpp ├── 462 最少移动次数使数组元素相等.cpp ├── 528 按权重随机选择.cpp ├── 168 Excel表列名称.cpp ├── 204 计数质数.cpp ├── 238 除自身以外数组的乘积.cpp ├── 384 打乱数组.cpp ├── 415 字符串相加.cpp ├── 382 链表随机节点.cpp └── 67 二进制求和.cpp ├── chapter 11 ├── 303 区域和检索-数组不可变.cpp ├── 503 下一个更大元素2.cpp ├── 287 寻找重复数.cpp ├── 217 存在重复元素.cpp ├── 560 和为K的子数组.cpp ├── 769 最多能完成排序的块.cpp ├── 739 每日温度.cpp ├── 448 找到所有数组中消失的数字.cpp ├── 1 两数之和.cpp ├── 240 搜索二维数组.cpp ├── 594 最长和谐子序列.cpp ├── 20 有效的括号.cpp ├── 313 超级丑数.cpp ├── 48 旋转图像.cpp ├── 304 二维区域和检索-矩阵不可变.cpp ├── 566 重塑矩阵.cpp ├── 128 最长连续序列.cpp ├── 239 滑动窗口最大值.cpp ├── 697 数组的度.cpp ├── 149 直线上最多的点数.cpp ├── 23 合并K个升序链表.cpp ├── 155 最小栈.cpp ├── 225 用队列实现栈.cpp ├── 232 用栈实现队列.cpp └── 870 优势洗牌.cpp ├── chapter 7 ├── 279 完全平方数.cpp ├── 70 爬楼梯.cpp ├── 343 整数分解.cpp ├── 53 最大子序和.cpp ├── 121 买卖股票的最佳时机.cpp ├── 198 打家劫舍.cpp ├── 300 最长递增子序列.cpp ├── 413 等差数列划分.cpp ├── 714 买卖股票的最佳时机含手续费.cpp ├── 64 最小路径和.cpp ├── 322 零钱兑换.cpp ├── 416 分割等和子集.cpp ├── 646 最长数对链.cpp ├── 309 买卖股票的最佳时期含冷冻期.cpp ├── 583 两个字符串的删除操作.cpp ├── 650 只有两个键的键盘.cpp ├── 72 编辑距离.cpp ├── 221 最大正方形.cpp ├── 213 打家劫舍2.cpp ├── 139 单词拆分.cpp ├── 188 买卖股票的最佳时机4.cpp ├── 474 零和一.cpp ├── 494 目标和.cpp ├── 1143 最长公共子序列.cpp ├── 376 最长摇摆子序列.cpp ├── 91 解码方法.cpp ├── 542 01矩阵.cpp └── 10 正则表达式匹配.cpp ├── chapter 13 ├── 160 相交链表.cpp ├── 206 反转链表.cpp ├── 24 两两交换链表中的节点.cpp ├── 83 删除排序链表中的重复元素.cpp ├── 328 奇偶链表.cpp ├── 21 合并两个有序链表.cpp ├── 19 删除链表倒数第n个节点.cpp ├── 234 回文链表.cpp └── 148 排序链表.cpp ├── chapter 12 ├── 242 有效的字母异位词.cpp ├── 3 无重复字符的最长子串.cpp ├── 205 同构字符串.cpp ├── 409 最长回文串.cpp ├── 647 回文子串.cpp ├── 5 最长回文子串.cpp └── 227 基本计算器2.cpp ├── chapter 6 ├── 77 组合.cpp ├── 46 全排列.cpp ├── 40 全组合2.cpp ├── 547 省份数量.cpp ├── 47 全排列2.cpp ├── 695 岛屿的最大面积.cpp ├── 257 二叉树的所有路径.cpp ├── 417 太平洋大西洋水流问题.cpp ├── 79 单词搜索.cpp ├── 51 N皇后.cpp ├── 130 被环绕的区域.cpp ├── 934 最短的桥.cpp └── 310 最小高度树.cpp ├── chapter 16 ├── 684 冗余连接.cpp ├── 146 LRU 缓存.cpp └── 380 常数时间插入删除和获取随机元素.cpp ├── chapter 8 ├── 932 漂亮数组.cpp ├── 312 戳气球.cpp └── 241 为运算表达式设置优先级.cpp └── README.md /chapter 5/75 颜色分类.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 5/75 颜色分类.cpp -------------------------------------------------------------------------------- /chapter 14/1110 删点成林.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 14/1110 删点成林.cpp -------------------------------------------------------------------------------- /chapter 2/135 分发糖果.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 2/135 分发糖果.cpp -------------------------------------------------------------------------------- /chapter 2/435 无重叠区间.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 2/435 无重叠区间.cpp -------------------------------------------------------------------------------- /chapter 2/455 分发饼干.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 2/455 分发饼干.cpp -------------------------------------------------------------------------------- /chapter 2/605 种花问题.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 2/605 种花问题.cpp -------------------------------------------------------------------------------- /chapter 2/665 非递减数列.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 2/665 非递减数列.cpp -------------------------------------------------------------------------------- /chapter 2/763 划分字母区间.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 2/763 划分字母区间.cpp -------------------------------------------------------------------------------- /chapter 3/142 环形链表2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 3/142 环形链表2.cpp -------------------------------------------------------------------------------- /chapter 3/167 两数之和2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 3/167 两数之和2.cpp -------------------------------------------------------------------------------- /chapter 3/633 平方数之和.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 3/633 平方数之和.cpp -------------------------------------------------------------------------------- /chapter 3/76 最小覆盖字串.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 3/76 最小覆盖字串.cpp -------------------------------------------------------------------------------- /chapter 4/69 x的平方根.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 4/69 x的平方根.cpp -------------------------------------------------------------------------------- /chapter 2/406 根据身高重建队列.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 2/406 根据身高重建队列.cpp -------------------------------------------------------------------------------- /chapter 3/680 验证回文字符串.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 3/680 验证回文字符串.cpp -------------------------------------------------------------------------------- /chapter 3/88 合并两个有序数组.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 3/88 合并两个有序数组.cpp -------------------------------------------------------------------------------- /chapter 5/347 前K个高频元素.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 5/347 前K个高频元素.cpp -------------------------------------------------------------------------------- /chapter 2/122 买股票的最佳时机2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 2/122 买股票的最佳时机2.cpp -------------------------------------------------------------------------------- /chapter 2/452 用最少数量的箭引爆气球.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 2/452 用最少数量的箭引爆气球.cpp -------------------------------------------------------------------------------- /chapter 4/4 寻找两个有序数组的中位数.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 4/4 寻找两个有序数组的中位数.cpp -------------------------------------------------------------------------------- /chapter 4/540 有序数组中的单一元素.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 4/540 有序数组中的单一元素.cpp -------------------------------------------------------------------------------- /chapter 4/81 搜索旋转排序数组2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 4/81 搜索旋转排序数组2.cpp -------------------------------------------------------------------------------- /chapter 5/215 数组中的第k个最大元素.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 5/215 数组中的第k个最大元素.cpp -------------------------------------------------------------------------------- /chapter 5/451 根据字符出现的频率排序.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 5/451 根据字符出现的频率排序.cpp -------------------------------------------------------------------------------- /chapter 4/154 寻找旋转排序数组中的最小值.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 4/154 寻找旋转排序数组中的最小值.cpp -------------------------------------------------------------------------------- /chapter 3/524 通过删除字母匹配到字典里最长单词.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 3/524 通过删除字母匹配到字典里最长单词.cpp -------------------------------------------------------------------------------- /chapter 4/34 在排序数组中查找元素的第一个和最后一个位置.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syarale/LeetCode101/HEAD/chapter 4/34 在排序数组中查找元素的第一个和最后一个位置.cpp -------------------------------------------------------------------------------- /chapter 10/342 4的幂.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 342. Power of Four 3 | 4 | class Solution { 5 | public: 6 | bool isPowerOfFour(int n) { 7 | return n > 0 && !(n & (n - 1)) && (n & 1431655765); 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /chapter 10/693 交替位二进制数.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 693. Binary Number with Alternating Bits 3 | 4 | class Solution { 5 | public: 6 | bool hasAlternatingBits(int n) { 7 | int tmp = n ^ (n>>1); 8 | return (tmp == INT_MAX || (tmp & (tmp+1)) == 0); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /chapter 10/136 只出现一次的数字.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 136. Single Number 3 | 4 | class Solution { 5 | public: 6 | int singleNumber(vector& nums) { 7 | int ans = 0; 8 | for (int i = 0; i < nums.size(); i++) { 9 | ans ^= nums[i]; 10 | } 11 | return ans; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /chapter 9/169 多数元素.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 169. Majority Element 3 | 4 | class Solution { 5 | public: 6 | int majorityElement(vector& nums) { 7 | // assert nums is valid... 8 | 9 | int len = nums.size(); 10 | sort(nums.begin(), nums.end()); 11 | return nums[len / 2]; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /chapter 10/461 汉明距离.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 461. Hamming Distance 3 | 4 | class Solution { 5 | public: 6 | int hammingDistance(int x, int y) { 7 | int diff = x ^ y; 8 | int count = 0; 9 | while (diff != 0) { 10 | count++; 11 | diff &= (diff - 1); 12 | } 13 | return count; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /chapter 10/476 数字的补数.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 476. Number Complement 3 | 4 | class Solution { 5 | public: 6 | int findComplement(int num) { 7 | int k = log2(num); 8 | int tmp = 0; 9 | for (int i = 0; i <= k; i++) { 10 | tmp <<= 1; 11 | tmp += 1; 12 | } 13 | 14 | return num ^ tmp; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /chapter 10/190 颠倒二进制位.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 190. Reverse Bits 3 | 4 | class Solution { 5 | public: 6 | uint32_t reverseBits(uint32_t n) { 7 | uint32_t res = 0; 8 | for (int i = 0; i < 32; i++) { 9 | res <<= 1; 10 | res += (n & 1); 11 | n >>= 1; 12 | } 13 | 14 | return res; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /chapter 10/268 丢失的数.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 268. Missing Number 3 | 4 | class Solution { 5 | public: 6 | int missingNumber(vector& nums) { 7 | int n = nums.size(); 8 | int total = (n * (n + 1)) / 2; 9 | int sum = 0; 10 | 11 | for (int i = 0; i < n; i++) { 12 | sum += nums[i]; 13 | } 14 | 15 | return total - sum; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /chapter 10/338 比特位计数.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 338. Counting Bits 3 | 4 | class Solution { 5 | public: 6 | vector countBits(int num) { 7 | vector dp(num + 1, 0); 8 | 9 | for (int i = 1; i <= num; i++) { 10 | if ((i & 1) == 1) { 11 | dp[i] = dp[i - 1] + 1; 12 | } else { 13 | dp[i] = dp[i >> 1]; 14 | } 15 | } 16 | 17 | return dp; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /chapter 9/326 3的幂.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 326. Power of Three 3 | 4 | class Solution { 5 | public: 6 | bool isPowerOfThree(int n) { 7 | if (n <= 0) { 8 | return false; 9 | } 10 | 11 | int pos = n; 12 | while (pos > 1) { 13 | if (pos % 3 != 0) { 14 | return false; 15 | } 16 | 17 | pos /= 3; 18 | } 19 | 20 | return true; 21 | 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /chapter 11/303 区域和检索-数组不可变.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 303. Range Sum Query - Immutable 3 | 4 | class NumArray { 5 | public: 6 | vector sum; 7 | 8 | NumArray(vector& nums) { 9 | int len = nums.size(); 10 | sum.resize(len + 1, 0); 11 | for (int i = 0; i < len; i++) { 12 | sum[i + 1] = sum[i] + nums[i]; 13 | } 14 | 15 | } 16 | 17 | int sumRange(int left, int right) { 18 | return sum[right + 1] - sum[left]; 19 | 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /chapter 7/279 完全平方数.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 279. Perfect Squares 3 | 4 | class Solution { 5 | public: 6 | const int MAX = 100001; 7 | int numSquares(int n) { 8 | // assert(n > 0); 9 | 10 | vector dp(n + 1, MAX); 11 | dp[0] = 0; 12 | for (int i = 1; i <= n; i++) { 13 | for (int k = 1; k * k <= i; k++) { 14 | dp[i] = min(dp[i], dp[i - k * k] + 1); 15 | } 16 | } 17 | 18 | return dp[n]; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /chapter 7/70 爬楼梯.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 70. Climbing Stairs 3 | 4 | class Solution { 5 | public: 6 | int climbStairs(int n) { 7 | // assert(n >= 0); 8 | int ptr1 = 1; 9 | int ptr2 = 2; 10 | 11 | if (n <= 2) { 12 | return n; 13 | } 14 | 15 | int num = 0; 16 | for (int i = 3; i <= n; i++) { 17 | int tmp = ptr1 + ptr2; 18 | ptr1 = ptr2; 19 | ptr2 = tmp; 20 | } 21 | 22 | num = ptr2; 23 | return num; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /chapter 7/343 整数分解.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 343. Integer Break 3 | 4 | class Solution { 5 | public: 6 | int integerBreak(int n) { 7 | if (n <= 1) { 8 | return -1; 9 | } 10 | 11 | vector dp(n + 1, 0); 12 | dp[1] = 1; 13 | dp[2] = 1; 14 | for (int i = 3; i <= n; i++) { 15 | for (int k = 1; k < i; k++) { 16 | dp[i] = max(dp[i], (i - k) * k); 17 | dp[i] = max(dp[i], dp[i - k] * k); 18 | } 19 | } 20 | 21 | return dp[n]; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /chapter 11/503 下一个更大元素2.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 503. Next Greater Element II 3 | 4 | class Solution { 5 | public: 6 | vector nextGreaterElements(vector& nums) { 7 | int n = nums.size(); 8 | vector ret(n, -1); 9 | stack stk; 10 | for (int i = 0; i < n * 2 - 1; i++) { 11 | while (!stk.empty() && nums[stk.top()] < nums[i % n]) { 12 | ret[stk.top()] = nums[i % n]; 13 | stk.pop(); 14 | } 15 | stk.push(i % n); 16 | } 17 | return ret; 18 | } 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /chapter 11/287 寻找重复数.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 287. Find the Duplicate Number 3 | 4 | class Solution { 5 | public: 6 | int findDuplicate(vector& nums) { 7 | // assert nums is valid... 8 | 9 | int len = nums.size(); 10 | 11 | for (int i = 0; i < len; i++) { 12 | int k = abs(nums[i]); 13 | 14 | if (nums[k] < 0) { 15 | return k; 16 | } 17 | 18 | nums[k] = -nums[k]; 19 | } 20 | 21 | // throw error... 22 | return INT_MIN; 23 | 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /chapter 9/172 阶乘后的0.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 172. Factorial Trailing Zeroes 3 | 4 | class Solution { 5 | public: 6 | int trailingZeroes(int n) { 7 | if(n <= 4) { 8 | return 0; 9 | } 10 | 11 | vectordp (n + 1, 0); 12 | dp[5] = 1; 13 | for (int i = 6; i <= n; i++) { 14 | if (i % 5 == 0) { 15 | dp[i] = dp[i/5] + 1; 16 | } 17 | } 18 | 19 | int count = 0; 20 | for (int i = 0; i <= n; i++) { 21 | count += dp[i]; 22 | } 23 | 24 | return count; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /chapter 11/217 存在重复元素.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 217. Contains Duplicate 3 | 4 | class Solution { 5 | public: 6 | bool containsDuplicate(vector& nums) { 7 | int len = nums.size(); 8 | unordered_set hash; 9 | 10 | if (nums.empty()) { 11 | return false; 12 | } 13 | 14 | for (int i = 0; i < len; i++) { 15 | if (hash.find(nums[i]) != hash.end()) { 16 | return true; 17 | } 18 | 19 | hash.insert(nums[i]); 20 | } 21 | 22 | return false; 23 | 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /chapter 13/160 相交链表.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 160. Intersection of Two Linked Lists 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 15 | ListNode* l1 = headA; 16 | ListNode* l2 = headB; 17 | while (l1 != l2) { 18 | l1 = l1 ? l1->next : headB; 19 | l2 = l2 ? l2->next : headA; 20 | } 21 | 22 | return l1; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /chapter 7/53 最大子序和.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 53. Maximum Subarray 3 | 4 | class Solution { 5 | public: 6 | int maxSubArray(vector& nums) { 7 | // assert(!nums.empty()); 8 | int len = nums.size(); 9 | vector dp(len, 0); 10 | 11 | if (len == 1) { 12 | return nums[0]; 13 | } 14 | 15 | dp[0] = nums[0]; 16 | int maxVal = dp[0]; 17 | for (int i = 1; i < len; i++){ 18 | dp[i] = max(dp[i - 1] + nums[i], nums[i]); 19 | maxVal = max(maxVal, dp[i]); 20 | } 21 | 22 | return maxVal; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /chapter 9/504 7进制数.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 504. Base 7 3 | 4 | class Solution { 5 | public: 6 | string convertToBase7(int num) { 7 | if (num == 0) { 8 | return "0"; 9 | } 10 | 11 | string str = ""; 12 | int absNum = abs(num); 13 | 14 | int curr = absNum; 15 | while (curr != 0) { 16 | int add = curr % 7; 17 | str = to_string(add) + str; 18 | 19 | curr /= 7; 20 | } 21 | 22 | if (num < 0) { 23 | str = "-" + str; 24 | } 25 | 26 | return str; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /chapter 11/560 和为K的子数组.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 560. Subarray Sum Equals K 3 | 4 | class Solution { 5 | public: 6 | int subarraySum(vector& nums, int k) { 7 | int len = nums.size(); 8 | int count = 0; 9 | int sum = 0; 10 | unordered_map hash; 11 | 12 | 13 | if (nums.empty()) { 14 | return 0; 15 | } 16 | 17 | hash[0] = 1; 18 | for (int i = 0; i < len; i++) { 19 | sum += nums[i]; 20 | count += hash[sum - k]; 21 | hash[sum]++; 22 | } 23 | 24 | return count; 25 | 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /chapter 9/462 最少移动次数使数组元素相等.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 462. Minimum Moves to Equal Array Elements II 3 | 4 | class Solution { 5 | public: 6 | int minMoves2(vector& nums) { 7 | if (nums.empty()) { 8 | return -1; // throw error 9 | } 10 | 11 | sort(nums.begin(), nums.end()); 12 | 13 | int len = nums.size(); 14 | int total = 0; 15 | int ptr1 = 0, ptr2 = len - 1; 16 | while (ptr1 < ptr2) { 17 | total += (nums[ptr2] - nums[ptr1]); 18 | ptr1 ++; 19 | ptr2 --; 20 | } 21 | 22 | return total; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /chapter 7/121 买卖股票的最佳时机.cpp: -------------------------------------------------------------------------------- 1 | // 121. Best Time to Buy and Sell Stock 2 | 3 | class Solution { 4 | public: 5 | int maxProfit(vector& prices) { 6 | int len = prices.size(); 7 | int minVal = 10001; 8 | int maxProfit = 0; 9 | 10 | if (prices.empty()) { 11 | return 0; 12 | } 13 | 14 | for (int i = 0; i < len; i++) { 15 | if (prices[i] < minVal) { 16 | minVal = prices[i]; 17 | } 18 | 19 | maxProfit = max(maxProfit, prices[i] - minVal); 20 | } 21 | 22 | return maxProfit; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /chapter 7/198 打家劫舍.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 198. House Robber 4 | 5 | class Solution { 6 | public: 7 | int rob(vector& nums) { 8 | int len = nums.size(); 9 | 10 | if (nums.empty()) { 11 | return 0; 12 | } 13 | 14 | if (len == 1) { 15 | return nums[0]; 16 | } 17 | 18 | vector dp(len, 0); 19 | dp[0] = nums[0]; 20 | dp[1] = max(nums[0], nums[1]); 21 | 22 | for (int i = 2; i < len; i++) { 23 | dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]); 24 | } 25 | 26 | return dp[len - 1]; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /chapter 11/769 最多能完成排序的块.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 769. Max Chunks To Make Sorted 3 | 4 | class Solution { 5 | public: 6 | int maxChunksToSorted(vector& arr) { 7 | int len = arr.size(); 8 | if (len <= 1) { 9 | return len; 10 | } 11 | 12 | int max = -1; 13 | int count = 0; 14 | for (int i = 0; i < len; i++) { 15 | if (arr[i] > max) { 16 | max = arr[i]; 17 | } 18 | 19 | if (max == i) { 20 | count++; 21 | max = -1; 22 | } 23 | } 24 | 25 | return count; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /chapter 9/528 按权重随机选择.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 528. Random Pick with Weight 3 | 4 | class Solution { 5 | private: 6 | vector preSum; 7 | public: 8 | Solution(vector& w) { 9 | preSum.assign(w.begin(), w.end()); 10 | partial_sum(preSum.begin(), preSum.end(), preSum.begin()); 11 | } 12 | 13 | int pickIndex() { 14 | int pos = rand() % preSum.back() + 1; 15 | return lower_bound(preSum.begin(), preSum.end(), pos) - preSum.begin(); 16 | 17 | } 18 | }; 19 | 20 | /** 21 | * Your Solution object will be instantiated and called as such: 22 | * Solution* obj = new Solution(w); 23 | * int param_1 = obj->pickIndex(); 24 | */ 25 | -------------------------------------------------------------------------------- /chapter 9/168 Excel表列名称.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 168. Excel Sheet Column Title 3 | 4 | class Solution { 5 | public: 6 | string convertToTitle(int columnNumber) { 7 | string title = ""; 8 | if (columnNumber <= 0) { 9 | return title; 10 | } 11 | 12 | int curr = columnNumber; 13 | while (curr > 0) { 14 | int pos = curr % 26; 15 | if (pos == 0) { 16 | title = "Z" + title; 17 | curr = curr / 26 - 1; 18 | } else { 19 | title = char('A' + pos - 1) + title; 20 | curr /= 26; 21 | } 22 | } 23 | 24 | return title; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /chapter 7/300 最长递增子序列.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 300. Longest Increasing Subsequence 3 | 4 | class Solution { 5 | public: 6 | int lengthOfLIS(vector& nums) { 7 | 8 | int len = nums.size(); 9 | vector dp(len, 1); 10 | if (len <= 1) { 11 | return len; 12 | } 13 | 14 | int maxLen = 1; 15 | for (int i = 1; i < len; i++) { 16 | for (int k = 0; k < i; k++) { 17 | if (nums[i] > nums[k]) { 18 | dp[i] = max(dp[i], dp[k] + 1); 19 | } 20 | } 21 | 22 | maxLen = max(maxLen, dp[i]); 23 | } 24 | 25 | return maxLen; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /chapter 14/104 二叉树的最大深度.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 104. Maximum Depth of Binary Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | int maxDepth(TreeNode* root) { 18 | if (root == NULL) { 19 | return 0; 20 | } 21 | 22 | return max(maxDepth(root->left), maxDepth(root->right)) + 1; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /chapter 7/413 等差数列划分.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 413. Arithmetic Slices 3 | 4 | class Solution { 5 | public: 6 | int numberOfArithmeticSlices(vector& nums) { 7 | int len = nums.size(); 8 | vector dp(len, 0); 9 | 10 | if (len < 3) { 11 | return 0; 12 | } 13 | 14 | for (int i = 2; i < len; i++) { 15 | if (nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]) { 16 | dp[i] = dp[i - 1] + 1; // dp[i - 1] + {nums[i - 2], nums[i - 1], nums[i] } 17 | } else { 18 | dp[i] = 0; 19 | } 20 | } 21 | 22 | int sum = accumulate(dp.begin(), dp.end(), 0); 23 | return sum; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /chapter 11/739 每日温度.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 739. Daily Temperatures 3 | 4 | class Solution { 5 | public: 6 | vector dailyTemperatures(vector& T) { 7 | int len = T.size(); 8 | vector days(len, 0); 9 | stack temper; 10 | 11 | if (T.empty()) { 12 | return days; 13 | } 14 | 15 | temper.push(0); 16 | for (int i = 1; i < len; i++) { 17 | int val = T[i]; 18 | while (!temper.empty() && T[temper.top()] < val) { 19 | days[temper.top()] = i - temper.top(); 20 | temper.pop(); 21 | } 22 | 23 | temper.push(i); 24 | } 25 | 26 | return days; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /chapter 12/242 有效的字母异位词.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 242. Valid Anagram 3 | 4 | class Solution { 5 | public: 6 | bool isAnagram(string s, string t) { 7 | int slen = s.size(); 8 | int tlen = t.size(); 9 | 10 | if (slen != tlen) { 11 | return false; 12 | } 13 | 14 | vector sdic(26, 0); 15 | vector tdic(26, 0); 16 | 17 | for (int i = 0; i < slen; i++) { 18 | //assert(slen == tlen); 19 | sdic[s[i] - 'a'] ++; 20 | tdic[t[i] - 'a'] ++; 21 | } 22 | 23 | for (int i = 0; i < 26; i++) { 24 | if (sdic[i] != tdic[i]) { 25 | return false; 26 | } 27 | } 28 | 29 | return true; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /chapter 7/714 买卖股票的最佳时机含手续费.cpp: -------------------------------------------------------------------------------- 1 | // 714. Best Time to Buy and Sell Stock with Transaction Fee 2 | 3 | class Solution { 4 | public: 5 | int maxProfit(vector& prices, int fee) { 6 | int len = prices.size(); 7 | vector dp0(len, 0); 8 | vector dp1(len, INT_MIN); 9 | 10 | if (prices.empty() || fee < 0) { 11 | return 0; 12 | } 13 | 14 | dp0[0] = 0; 15 | dp1[0] = -prices[0] - fee; 16 | 17 | for (int i = 1; i < len; i++) { 18 | dp0[i] = max(dp0[i - 1], dp1[i - 1] + prices[i]); 19 | dp1[i] = max(dp1[i - 1], dp0[i - 1] - prices[i] - fee); 20 | } 21 | 22 | return max(dp0[len - 1], dp1[len - 1]); 23 | 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /chapter 11/448 找到所有数组中消失的数字.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 448. Find All Numbers Disappeared in an Array 3 | 4 | class Solution { 5 | public: 6 | vector findDisappearedNumbers(vector& nums) { 7 | int len = nums.size(); 8 | vector res; 9 | 10 | if (nums.empty()) { 11 | return res; 12 | } 13 | 14 | for (int i = 0; i < len; i++) { 15 | int pos = abs(nums[i]) - 1; 16 | if (nums[pos] > 0) { 17 | nums[pos] = - nums[pos]; 18 | } 19 | } 20 | 21 | for (int i = 0; i < len; i++) { 22 | if (nums[i] > 0) { 23 | res.push_back(i + 1); 24 | } 25 | } 26 | 27 | return res; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /chapter 9/204 计数质数.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 204. Count Primes 3 | 4 | class Solution { 5 | public: 6 | int countPrimes(int n) { 7 | if (n <= 1) { 8 | return 0; 9 | } 10 | 11 | vector prime(n, true); 12 | prime[0] = false; 13 | prime[1] = false; 14 | 15 | for (int i = 2; i * i < n; i++) { 16 | if (prime[i]) { 17 | for (int j = i; j * i < n; j++) { 18 | prime[j * i] = false; 19 | } 20 | } 21 | } 22 | 23 | int count = 0; 24 | for (int i = 0; i < n; i++) { 25 | if (prime[i]) { 26 | count++; 27 | } 28 | } 29 | 30 | return count; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /chapter 7/64 最小路径和.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 64. Minimum Path Sum 3 | 4 | class Solution { 5 | public: 6 | int minPathSum(vector>& grid) { 7 | if (grid.empty()) { 8 | return 0; 9 | } 10 | 11 | int row = grid.size(); 12 | int col = grid[0].size(); 13 | 14 | vector dp(col, 0); 15 | dp[0] = grid[0][0]; 16 | for (int j = 1; j < col; j++) { 17 | dp[j] = dp[j - 1] + grid[0][j]; 18 | } 19 | 20 | for (int i = 1; i < row; i++) { 21 | dp[0] = dp[0] + grid[i][0]; 22 | 23 | for (int j = 1; j < col; j++) { 24 | dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]; 25 | } 26 | } 27 | 28 | return dp[col - 1]; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /chapter 10/260 只出现一次的数字3.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 260. Single Number III 3 | 4 | class Solution { 5 | public: 6 | vector singleNumber(vector& nums) { 7 | int ans = 0; 8 | for (int i = 0; i < nums.size(); i++) { 9 | ans ^= nums[i]; 10 | } 11 | 12 | int sign = 0; 13 | if (ans == INT_MIN) { 14 | sign = 1; 15 | } else { 16 | sign = (ans & -ans); 17 | } 18 | int x = 0, y = 0; 19 | for (int i = 0; i < nums.size(); i++) { 20 | if ((nums[i] & sign) == 0) { 21 | x ^= nums[i]; 22 | } else { 23 | y ^= nums[i]; 24 | } 25 | } 26 | 27 | vector ret; 28 | ret.push_back(x); 29 | ret.push_back(y); 30 | return ret; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /chapter 7/322 零钱兑换.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 322. Coin Change 3 | 4 | class Solution { 5 | public: 6 | const int MAX = 10001; 7 | int coinChange(vector& coins, int amount) { 8 | if (amount == 0) { 9 | return 0; 10 | } 11 | 12 | if (coins.empty()) { 13 | return -1; 14 | } 15 | 16 | int len = coins.size(); 17 | vector dp(amount + 1, MAX); 18 | dp[0] = 0; 19 | 20 | for (int i = 1; i <= len; i++) { 21 | for (int j = coins[i - 1]; j <= amount; j++) { 22 | dp[j] = min(dp[j], dp[j - coins[i - 1]] + 1); 23 | } 24 | } 25 | 26 | if (dp[amount] < MAX) { 27 | return dp[amount]; 28 | } else { 29 | return -1; 30 | } 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /chapter 11/1 两数之和.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 1. Two Sum 3 | 4 | class Solution { 5 | public: 6 | vector twoSum(vector& nums, int target) { 7 | int len = nums.size(); 8 | unordered_map hash; 9 | vector res; 10 | 11 | 12 | if (nums.empty() || len == 1) { 13 | return res; 14 | } 15 | 16 | for (int i = 0; i < len; i++) { 17 | unordered_map::iterator pos = hash.find(target - nums[i]); 18 | if (pos != hash.end()) { 19 | res.push_back(pos->second); 20 | res.push_back(i); 21 | 22 | // only one valid solution 23 | break; 24 | } 25 | 26 | hash[nums[i]] = i; 27 | } 28 | 29 | return res; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /chapter 9/238 除自身以外数组的乘积.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 238. Product of Array Except Self 3 | 4 | class Solution { 5 | public: 6 | vector productExceptSelf(vector& nums) { 7 | vector res; 8 | if (nums.empty()) { 9 | return res; 10 | } 11 | 12 | int len = nums.size(); 13 | res.resize(len, 0); 14 | int tmp = 1; 15 | for (int i = 0; i < len; i++) { 16 | tmp *= nums[i]; 17 | res[i] = tmp; 18 | } 19 | 20 | int right = 1; 21 | for (int i = len - 1; i >= 0; i--) { 22 | if (i == 0) { 23 | res[i] = right; 24 | continue; 25 | } 26 | 27 | res[i] = res[i - 1] * right; 28 | right *= nums[i]; 29 | } 30 | 31 | return res; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /chapter 14/226 翻转二叉树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 226. Invert Binary Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | TreeNode* invertTree(TreeNode* root) { 18 | if (root == NULL) { 19 | return NULL; 20 | } 21 | 22 | invertTree(root->left); 23 | invertTree(root->right); 24 | TreeNode* tmp = root->left; 25 | root->left = root->right; 26 | root->right = tmp; 27 | 28 | return root; 29 | 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /chapter 11/240 搜索二维数组.cpp: -------------------------------------------------------------------------------- 1 | // 240. Search a 2D Matrix II 2 | 3 | class Solution { 4 | public: 5 | bool searchMatrix(vector>& matrix, int target) { 6 | if (matrix.empty() || matrix[0].empty()) { 7 | return false; 8 | } 9 | 10 | int row = matrix.size(); 11 | int col = matrix[0].size(); 12 | if (target < matrix[0][0] || target > matrix[row - 1][col - 1]) { 13 | return false; 14 | } 15 | 16 | int x = row - 1; 17 | int y = 0; 18 | 19 | while (x >= 0 && y < col) { 20 | if (matrix[x][y] == target) { 21 | return true; 22 | } else if (matrix[x][y] > target) { 23 | x--; 24 | } else { 25 | y++; 26 | } 27 | } 28 | 29 | return false; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /chapter 7/416 分割等和子集.cpp: -------------------------------------------------------------------------------- 1 | // 416. Partition Equal Subset Sum 2 | 3 | class Solution { 4 | public: 5 | bool canPartition(vector& nums) { 6 | if (nums.empty()) { 7 | return 0; 8 | } 9 | 10 | int sum = accumulate(nums.begin(), nums.end(), 0); 11 | if (sum % 2 != 0) { 12 | return false; 13 | } 14 | 15 | int len = nums.size(); 16 | int target = sum / 2; 17 | vector dp(target + 1, false); 18 | dp[0] = true; 19 | 20 | if (target >= nums[0]) { 21 | dp[nums[0]] = true; 22 | } 23 | 24 | for (int i = 1; i < len; i++) { 25 | for (int j = target; j >= nums[i]; j--) { 26 | dp[j] = dp[j] || dp[j - nums[i]]; 27 | } 28 | } 29 | 30 | return dp[target]; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /chapter 11/594 最长和谐子序列.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 594. Longest Harmonious Subsequence 3 | 4 | class Solution { 5 | public: 6 | int findLHS(vector& nums) { 7 | int len = nums.size(); 8 | unordered_map hash; // hash is: val:count 9 | 10 | if (len <= 1) { 11 | return 0; 12 | } 13 | 14 | for (int i = 0; i < len; i++) { 15 | hash[nums[i]] ++; 16 | } 17 | 18 | int maxLen = 0; 19 | unordered_map::iterator it; 20 | for (it = hash.begin(); it != hash.end(); it++) { 21 | int val = it->first; 22 | 23 | if (hash.find(val + 1) != hash.end()) { 24 | int num = hash[val] + hash[val + 1]; 25 | maxLen = max(maxLen, num); 26 | } 27 | } 28 | 29 | return maxLen; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /chapter 7/646 最长数对链.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 646. Maximum Length of Pair Chain 3 | 4 | class Solution { 5 | public: 6 | bool cmp(vector p1, vector p2) { 7 | return p1[1] < p2[1]; 8 | } 9 | 10 | int findLongestChain(vector>& pairs) { 11 | int len = pairs.size(); 12 | 13 | if (pairs.empty()) { 14 | return 0; 15 | } 16 | 17 | sort(pairs.begin(), pairs.end(), cmp); 18 | vector dp(len, 0); 19 | dp[0] = 1; 20 | int maxLen = dp[0]; 21 | 22 | for (int i = 1; i < len; i++) { 23 | for (int j = 0; j < i; j++) { 24 | if (pairs[j][1] < pairs[i][0]) { 25 | dp[i] = max(dp[i], dp[j] + 1); 26 | } 27 | } 28 | maxLen = max(maxLen, dp[i]); 29 | } 30 | 31 | return maxLen; 32 | 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /chapter 12/3 无重复字符的最长子串.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 3. Longest Substring Without Repeating Characters 3 | 4 | class Solution { 5 | public: 6 | int lengthOfLongestSubstring(string s) { 7 | int len = s.size(); 8 | unordered_map charPos; 9 | 10 | if (s.empty() || len == 1) { 11 | return len; 12 | } 13 | 14 | charPos[s[0]] = 0; 15 | int i = 0; 16 | int maxSub = 1; 17 | for (int j = 1; j < len; j++) { 18 | char ch = s[j]; 19 | if (charPos.find(ch) != charPos.end()) { 20 | int loc = charPos[ch]; 21 | 22 | for (int x = i; x <= loc; x++) { 23 | charPos.erase(s[x]); 24 | } 25 | 26 | i = loc + 1; 27 | } 28 | 29 | charPos[ch] = j; 30 | maxSub = max(maxSub, j - i + 1); 31 | } 32 | return maxSub; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /chapter 13/206 反转链表.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 206. Reverse Linked List 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode() : val(0), next(nullptr) {} 10 | * ListNode(int x) : val(x), next(nullptr) {} 11 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | ListNode* reverseList(ListNode* head) { 17 | ListNode* rhead = head; 18 | ListNode* rtail = head; 19 | 20 | if (head == nullptr) { 21 | return nullptr; 22 | } 23 | 24 | ListNode* ptr = head->next; 25 | rtail->next = nullptr; 26 | while (ptr != nullptr) { 27 | ListNode* tmp = ptr->next; 28 | ptr->next = rhead; 29 | rhead = ptr; 30 | ptr = tmp; 31 | } 32 | 33 | return rhead; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /chapter 7/309 买卖股票的最佳时期含冷冻期.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 309. Best Time to Buy and Sell Stock with Cooldown 3 | 4 | class Solution { 5 | public: 6 | 7 | const int MIN_VAL = -10001; 8 | int maxProfit(vector& prices) { 9 | int len = prices.size(); 10 | 11 | if (prices.empty() || len == 1) { 12 | return 0; 13 | } 14 | 15 | vector adp0(len, 0); 16 | vector bdp0(len, 0); 17 | vector dp1(len, MIN_VAL); 18 | vector wait0(len, 0); 19 | 20 | dp1[0] = -prices[0]; 21 | 22 | for (int i = 1; i < len; i++) { 23 | adp0[i] = max(adp0[i - 1], wait0[i - 1]); 24 | dp1[i] = max(dp1[i - 1], adp0[i] - prices[i]); 25 | bdp0[i] = dp1[i] + prices[i]; 26 | wait0[i] = bdp0[i - 1]; 27 | } 28 | 29 | return max(wait0[len - 1], max(adp0[len - 1], bdp0[len - 1])); 30 | 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /chapter 13/24 两两交换链表中的节点.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 24. Swap Nodes in Pairs 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode() : val(0), next(nullptr) {} 10 | * ListNode(int x) : val(x), next(nullptr) {} 11 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | ListNode* swapPairs(ListNode* head) { 17 | ListNode* dummy = new ListNode(); 18 | ListNode* rtail = dummy; 19 | 20 | ListNode* ptr = head; 21 | while (ptr != nullptr && ptr->next != nullptr) { 22 | ListNode* prev = ptr; 23 | ListNode* after = ptr->next; 24 | ptr = after->next; 25 | 26 | after->next = prev; 27 | rtail->next = after; 28 | rtail = prev; 29 | } 30 | 31 | rtail->next = ptr; 32 | return dummy->next; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /chapter 6/77 组合.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 77. Combinations 3 | 4 | class Solution { 5 | public: 6 | void dfs(vector& curr, int depth, int minPos, int n, int k, 7 | vector >& res) { 8 | 9 | if (depth == k) { 10 | res.push_back(curr); 11 | return; 12 | } 13 | 14 | int extend = k - depth; 15 | for (int i = minPos; i <= (n - extend + 1); i++) { 16 | 17 | curr.push_back(i); 18 | dfs(curr, depth + 1, i + 1, n, k, res); 19 | curr.pop_back(); 20 | } 21 | 22 | return; 23 | } 24 | 25 | vector> combine(int n, int k) { 26 | int len = n; 27 | // vector used(len + 1, false); 28 | // used[0] = true; 29 | 30 | vector curr; 31 | vector > res; 32 | 33 | dfs(curr, 0, 1, n, k, res); 34 | return res; 35 | 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /chapter 7/583 两个字符串的删除操作.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 583. Delete Operation for Two Strings 3 | 4 | class Solution { 5 | public: 6 | int minDistance(string word1, string word2) { 7 | int len1 = word1.size(); 8 | int len2 = word2.size(); 9 | 10 | vector > dp(len1 + 1, vector (len2 + 1, 0)); 11 | dp[0][0] = 0; 12 | for (int j = 0; j <= len2; j++) { 13 | dp[0][j] = j; 14 | } 15 | 16 | for (int i = 0; i <= len1; i++) { 17 | dp[i][0] = i; 18 | } 19 | 20 | for (int i = 1; i <= len1; i++) { 21 | for (int j = 1; j <= len2; j++) { 22 | if (word1[i - 1] == word2[j - 1]) { 23 | dp[i][j] = dp[i - 1][j - 1]; 24 | } else { 25 | dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1; 26 | } 27 | } 28 | } 29 | 30 | return dp[len1][len2]; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /chapter 12/205 同构字符串.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 205. Isomorphic Strings 3 | 4 | class Solution { 5 | public: 6 | bool isIsomorphic(string s, string t) { 7 | int slen = s.size(); 8 | int tlen = t.size(); 9 | 10 | if (slen != tlen) { 11 | return false; 12 | } 13 | 14 | unordered_set hash; 15 | unordered_map dic; 16 | for (int i = 0; i < slen; i++) { 17 | //assert(slen == tlen); 18 | 19 | if (dic.find(s[i]) == dic.end()) { 20 | if (hash.find(t[i]) != hash.end()) { 21 | return false; 22 | } 23 | 24 | dic[s[i]] = t[i]; 25 | hash.insert(t[i]); 26 | continue; 27 | } 28 | 29 | // assert(dic.find(s[i]) != dic.end()); 30 | if (dic[s[i]] != t[i]) { 31 | return false; 32 | } 33 | 34 | } 35 | 36 | return true; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /chapter 12/409 最长回文串.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 409. Longest Palindrome 3 | 4 | class Solution { 5 | public: 6 | int longestPalindrome(string s) { 7 | int len = s.size(); 8 | 9 | if (s.empty() || len == 1) { 10 | return len; 11 | } 12 | 13 | unordered_map dic; 14 | for (int i = 0; i < len; i++) { 15 | dic[s[i]]++; 16 | } 17 | 18 | int palLen = 0, single = 0; 19 | unordered_map::iterator it; 20 | for (it = dic.begin(); it != dic.end(); it++) { 21 | int num = it->second; 22 | if (num % 2 == 0) { 23 | palLen += num; 24 | } else { 25 | if (num > 1) { 26 | palLen += (num - 1); 27 | } 28 | 29 | single += 1; 30 | } 31 | } 32 | 33 | if (single > 0) { 34 | palLen += 1; 35 | } 36 | 37 | return palLen; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /chapter 7/650 只有两个键的键盘.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 650. 2 Keys Keyboard 3 | 4 | class Solution { 5 | public: 6 | const int MAX = 1001; 7 | int minSteps(int n) { 8 | // assert(n >= 1); 9 | 10 | if (n == 1) { 11 | return 0; 12 | } 13 | 14 | vector > dp(n + 1, vector (n + 1, MAX)); 15 | dp[0][1] = 0; 16 | 17 | int minNum = MAX; 18 | for (int i = 1; i <= n; i ++) { 19 | for (int j = i + 1; j <= n; j++) { 20 | if (j % i != 0) { 21 | dp[i][j] = min(dp[i][j], dp[i][j - i] + 1); 22 | continue; 23 | } 24 | 25 | for (int k = 0; k < i; k++) { 26 | dp[i][j] = min(d[i][j], dp[k][i] + 2); 27 | } 28 | } 29 | 30 | minNum = min(minNum, dp[i][n]); 31 | } 32 | 33 | return minNum; 34 | 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /chapter 11/20 有效的括号.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 20. Valid Parentheses 3 | 4 | class Solution { 5 | public: 6 | bool isValid(string s) { 7 | // assert(!s.empty()); 8 | 9 | int len = s.size(); 10 | stack stk; 11 | for (int i = 0; i < len; i++){ 12 | if (s[i] == '{' || s[i] == '(' || s[i] == '[') { 13 | stk.push(s[i]); 14 | continue; 15 | } 16 | 17 | if (stk.empty()) { 18 | return false; 19 | } 20 | 21 | char ch = stk.top(); 22 | if ((ch == '{' && s[i] == '}') || (ch == '(' && s[i] == ')') || 23 | (ch == '[' && s[i] == ']')) { 24 | 25 | stk.pop(); 26 | } else { 27 | return false; 28 | } 29 | } 30 | 31 | if (stk.empty()) { 32 | return true; 33 | } else { 34 | return false; 35 | } 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /chapter 11/313 超级丑数.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 313. Super Ugly Number 3 | 4 | class Solution { 5 | public: 6 | int nthSuperUglyNumber(int n, vector& primes) { 7 | // assert(!primes.empty()); 8 | 9 | int uglyVal = 0; 10 | int len = primes.size(); 11 | unordered_set exist; 12 | priority_queue, greater > heap; 13 | heap.push(1); 14 | exist.insert(1); 15 | 16 | for (int i = 1; i <= n; i++) { 17 | uglyVal = heap.top(); 18 | heap.pop(); 19 | 20 | if (i == n) { 21 | break; 22 | } 23 | 24 | for (int j = 0; j < len; j++) { 25 | int tmp = uglyVal * primes[j]; 26 | if (exist.find(tmp) != exist.end()) { 27 | heap.push(tmp); 28 | exist.insert(tmp); 29 | } 30 | } 31 | } 32 | 33 | return uglyVal; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /chapter 14/669 修剪二叉搜索树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 669. Trim a Binary Search Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | TreeNode* trimBST(TreeNode* root, int low, int high) { 18 | if (root == NULL) { 19 | return NULL; 20 | } 21 | 22 | if (root->val < low) { 23 | return trimBST(root->right, low, high); 24 | } else if (root->val > high) { 25 | return trimBST(root->left, low, high); 26 | } 27 | 28 | root->left = trimBST(root->left, low, high); 29 | root->right = trimBST(root->right, low, high); 30 | return root; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /chapter 14/235 二叉搜索树的最近公共祖先.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 235. Lowest Common Ancestor of a Binary Search Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | 14 | class Solution { 15 | public: 16 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 17 | if (root == NULL || p == NULL || q == NULL) { 18 | return NULL; 19 | } 20 | 21 | TreeNode* ptr = root; 22 | int minVal = min(p->val, q->val); 23 | int maxVal = max(p->val, q->val); 24 | 25 | while (ptr != NULL) { 26 | if (ptr->val < minVal) { 27 | ptr = ptr->right; 28 | } else if (ptr->val > maxVal) { 29 | ptr = ptr->left; 30 | } else { 31 | break; 32 | } 33 | } 34 | 35 | return ptr; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /chapter 7/72 编辑距离.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 72. Edit Distance 3 | 4 | class Solution { 5 | public: 6 | int minDistance(string word1, string word2) { 7 | int len1 = word1.size(); 8 | int len2 = word2.size(); 9 | 10 | vector > dp(len1 + 1, vector(len2 + 1, 0)); 11 | for (int i = 0; i <= len1; i++) { 12 | dp[i][0] = i; 13 | } 14 | 15 | for (int j = 0; j <= len2; j++) { 16 | dp[0][j] = j; 17 | } 18 | 19 | for (int i = 1; i <= len1; i++) { 20 | for (int j = 1; j <= len2; j++) { 21 | 22 | if (word1[i - 1] == word2[j - 1]) { 23 | dp[i][j] = dp[i - 1][j - 1]; 24 | } else { 25 | dp[i][j] = dp[i - 1][j - 1] + 1; 26 | } 27 | 28 | dp[i][j] = min(dp[i][j], min(dp[i - 1][j], dp[i][j - 1]) + 1); 29 | 30 | } 31 | } 32 | 33 | return dp[len1][len2]; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /chapter 7/221 最大正方形.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 221. Maximal Square 3 | 4 | class Solution { 5 | public: 6 | int maximalSquare(vector>& matrix) { 7 | if (matrix.empty()) { 8 | return 0; 9 | } 10 | 11 | int row = matrix.size(); 12 | int col = matrix[0].size(); 13 | int maxSide = 0; 14 | vector > dp(row, vector (col, 0)); 15 | 16 | for (int i = 0; i < row; i++) { 17 | for (int j = 0; j < col; j++) { 18 | if (matrix[i][j] == '0') { 19 | dp[i][j] = 0; 20 | continue; 21 | } 22 | 23 | if (i == 0 || j == 0) { 24 | dp[i][j] = 1; 25 | } else { 26 | dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1; 27 | } 28 | 29 | maxSide = max(maxSide, dp[i][j]); 30 | } 31 | } 32 | 33 | return maxSide * maxSide; 34 | 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /chapter 7/213 打家劫舍2.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 213. House Robber II 3 | 4 | class Solution { 5 | public: 6 | int rob(vector& nums) { 7 | int len = nums.size(); 8 | 9 | if (nums.empty()) { 10 | return 0; 11 | } 12 | 13 | if (len == 1) { 14 | return nums[0]; 15 | } else if (len == 2) { 16 | return max(nums[0], nums[1]); 17 | } else if (len == 3) { 18 | return max(nums[0], max(nums[1], nums[2])); 19 | } 20 | 21 | int maxVal = 0; 22 | vector dp(len, 0); 23 | 24 | dp[0] = nums[0]; 25 | dp[1] = max(nums[0], nums[1]); 26 | 27 | for (int i = 2; i < len - 1; i++) { 28 | dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]); 29 | } 30 | 31 | maxVal = dp[len - 2]; 32 | 33 | for (int i = len - 1; i >= 1; i--) { 34 | dp[i] = max(dp[i + 1], dp[i + 2] + nums[i]); 35 | } 36 | 37 | maxVal = max(maxVal, dp[1]); 38 | return maxVal; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /chapter 14/101 对称二叉树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 101. Symmetric Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | bool isSymTrees(TreeNode* root1, TreeNode* root2) { 18 | if (root1 == NULL && root2 == NULL) { 19 | return true; 20 | } 21 | 22 | if (root1 == NULL || root2 == NULL) { 23 | return false; 24 | } 25 | 26 | if (root1 -> val != root2->val) { 27 | return false; 28 | } 29 | 30 | return isSymTrees(root1->left, root2->right) && isSymTrees(root1->right, root2->left); 31 | } 32 | 33 | bool isSymmetric(TreeNode* root) { 34 | return isSymTrees(root->left, root->right); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /chapter 14/530 二叉搜索树的最小绝对差.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 530. Minimum Absolute Difference in BST 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | int getMinimumDifference(TreeNode* root) { 16 | int minDiff = INT_MAX; 17 | TreeNode* pred = NULL; 18 | TreeNode* ptr = root; 19 | stack stk; 20 | 21 | while (ptr != NULL || !stk.empty()) { 22 | while (ptr != NULL) { 23 | stk.push(ptr); 24 | ptr = ptr->left; 25 | } 26 | 27 | ptr = stk.top(); 28 | stk.pop(); 29 | 30 | if (pred != NULL) { 31 | minDiff = min(minDiff, abs(ptr->val - pred->val)); 32 | } 33 | 34 | pred = ptr; 35 | ptr = ptr->right; 36 | } 37 | 38 | return minDiff; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /chapter 9/384 打乱数组.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 384. Shuffle an Array 3 | 4 | class Solution { 5 | private: 6 | vector origin; 7 | 8 | public: 9 | Solution(vector& nums) { 10 | origin.assign(nums.begin(), nums.end()); 11 | } 12 | 13 | /** Resets the array to its original configuration and return it. */ 14 | vector reset() { 15 | return origin; 16 | 17 | } 18 | 19 | /** Returns a random shuffling of the array. */ 20 | vector shuffle() { 21 | int len = origin.size(); 22 | vector shuffled(origin); 23 | 24 | for (int i = 0; i < len; i++) { 25 | int another = rand() % len; 26 | int tmp = shuffled[i]; 27 | shuffled[i] = shuffled[another]; 28 | shuffled[another] = tmp; 29 | } 30 | 31 | return shuffled; 32 | } 33 | }; 34 | 35 | /** 36 | * Your Solution object will be instantiated and called as such: 37 | * Solution* obj = new Solution(nums); 38 | * vector param_1 = obj->reset(); 39 | * vector param_2 = obj->shuffle(); 40 | */ 41 | -------------------------------------------------------------------------------- /chapter 14/617 合并二叉树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 617. Merge Two Binary Trees 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) { 18 | if (root1 == NULL && root2 == NULL) { 19 | return NULL; 20 | } 21 | 22 | if (root1 == NULL && root2 != NULL) { 23 | return root2; 24 | } 25 | 26 | if (root1 != NULL && root2 == NULL) { 27 | return root1; 28 | } 29 | 30 | root1->val += root2->val; 31 | root1->left = mergeTrees(root1->left, root2->left); 32 | root1->right = mergeTrees(root1->right, root2->right); 33 | 34 | return root1; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /chapter 13/83 删除排序链表中的重复元素.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 83. Remove Duplicates from Sorted List 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * struct ListNode { 8 | * int val; 9 | * ListNode *next; 10 | * ListNode() : val(0), next(nullptr) {} 11 | * ListNode(int x) : val(x), next(nullptr) {} 12 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | ListNode* deleteDuplicates(ListNode* head) { 18 | if (head == nullptr) { 19 | return head; 20 | } 21 | 22 | ListNode* rhead = head, *rtail = head; 23 | ListNode* ptr = head->next; 24 | while (ptr != nullptr) { 25 | if (ptr->val != rtail->val) { 26 | rtail->next = ptr; 27 | rtail = rtail->next; 28 | ptr = ptr->next; 29 | } else { 30 | ListNode* tmp = ptr; 31 | ptr = ptr->next; 32 | delete tmp; 33 | } 34 | } 35 | 36 | rtail->next = nullptr; 37 | return rhead; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /chapter 10/318 最大单词长度乘积.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 318. Maximum Product of Word Lengths 3 | 4 | class Solution { 5 | public: 6 | int build(string str) { 7 | int res = 0; 8 | for (int i = 0; i < str.size(); i++) { 9 | int loc = str[i] - 'a'; 10 | int tmp = 1; 11 | for (int j = 0; j < loc; j++) { 12 | tmp <<= 1; 13 | } 14 | 15 | res |= tmp; 16 | } 17 | 18 | return res; 19 | } 20 | 21 | int maxProduct(vector& words) { 22 | map hash; 23 | 24 | for (int i = 0; i < words.size(); i++) { 25 | hash[words[i]] = build(words[i]); 26 | } 27 | 28 | int maxVal = 0; 29 | for (int i = 0; i < words.size(); i++) { 30 | for (int j = i + 1; j < words.size(); j++) { 31 | if ((hash[words[i]] & hash[words[j]]) == 0) { 32 | int len = words[i].size() * words[j].size(); 33 | maxVal = max(maxVal, len); 34 | } 35 | } 36 | } 37 | 38 | return maxVal; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /chapter 11/48 旋转图像.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 48. Rotate Image 3 | 4 | class Solution { 5 | public: 6 | void rotateEdge(vector >& matrix, int k, int len) { 7 | // assert(k < matrix.size() / 2); 8 | // assert(len == matrix.size() - k * 2); 9 | for (int l = 0; l < len - 1; l++) { 10 | int tmp = matrix[k][k + l]; 11 | matrix[k][k + l] = matrix[k + len - 1 - l][k]; 12 | matrix[k + len - 1 - l][k] = matrix[k + len - 1][k + len - 1 - l]; 13 | matrix[k + len - 1][k + len - 1 - l] = matrix[k + l][k + len - 1]; 14 | matrix[k + l][k + len - 1] = tmp; 15 | } 16 | 17 | return; 18 | } 19 | 20 | void rotate(vector>& matrix) { 21 | if (matrix.empty() || matrix[0].empty()) { 22 | return; 23 | } 24 | 25 | int n = matrix.size(); 26 | // assert(matrix[0].size() == n); 27 | 28 | for (int k = 0; k < (n / 2); k++) { 29 | int len = n - k * 2; 30 | rotateEdge(matrix, k, len); 31 | } 32 | 33 | return; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /chapter 7/139 单词拆分.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 139. Word Break 3 | 4 | class Solution { 5 | public: 6 | bool wordBreak(string s, vector& wordDict) { 7 | if (s.empty() || wordDict.empty()) { 8 | return false; 9 | } 10 | 11 | int sLen = s.size(); 12 | vector dp(sLen, false); 13 | for (int i = 0; i < sLen; i++) { 14 | if (dp[i]) { 15 | continue; 16 | } 17 | 18 | for (int j = 0; j < wordDict.size(); j++) { 19 | string word = wordDict[j]; 20 | int wordLen = word.size(); 21 | 22 | if (i - wordLen + 1 >= 0 && s.substr(i - wordLen + 1, wordLen) == word) { 23 | if (i - wordLen < 0) { 24 | dp[i] = true; 25 | } else { 26 | dp[i] = dp[i - wordLen]; 27 | } 28 | 29 | if (dp[i]) { 30 | break; 31 | } 32 | } 33 | } 34 | } 35 | 36 | return dp[sLen - 1]; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /chapter 11/304 二维区域和检索-矩阵不可变.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 304. Range Sum Query 2D - Immutable 3 | 4 | 5 | class NumMatrix { 6 | private: 7 | vector > sum; 8 | public: 9 | NumMatrix(vector>& matrix) { 10 | // assert(!matrix.empty()); 11 | // assert(!matrix[0].empty()); 12 | 13 | int row = matrix.size(); 14 | int col = matrix[0].size(); 15 | 16 | sum.resize(row + 1, vector (col + 1, 0)); 17 | for (int i = 1; i < row + 1; i++) { 18 | for (int j = 1; j < col + 1; j++) { 19 | sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] 20 | + matrix[i - 1][j - 1]; 21 | } 22 | } 23 | 24 | } 25 | 26 | int sumRegion(int row1, int col1, int row2, int col2) { 27 | return (sum[row2 + 1][col2 + 1] - sum[row1][col2 + 1] 28 | - sum[row2 + 1][col1] + sum[row1][col1]); 29 | 30 | } 31 | }; 32 | 33 | /** 34 | * Your NumMatrix object will be instantiated and called as such: 35 | * NumMatrix* obj = new NumMatrix(matrix); 36 | * int param_1 = obj->sumRegion(row1,col1,row2,col2); 37 | */ 38 | -------------------------------------------------------------------------------- /chapter 12/647 回文子串.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 647. Palindromic Substrings 3 | 4 | class Solution { 5 | public: 6 | int countSubstrings(string s) { 7 | int len = s.size(); 8 | if (len <= 1) { 9 | return len; 10 | } 11 | 12 | int count = 0; 13 | vector > dp(len, vector(len, false)); 14 | for (int i = 0; i <= len - 2; i++) { 15 | dp[i][i] = true; 16 | count++; 17 | 18 | if (s[i] == s[i + 1]) { 19 | dp[i][i + 1] = true; 20 | count++; 21 | } else { 22 | dp[i][i + 1] = false; 23 | } 24 | } 25 | 26 | dp[len - 1][len - 1] = true; 27 | count ++; 28 | 29 | for (int l = 2; l < len; l++) { 30 | for (int i = 0; i < len - l; i++) { 31 | if (s[i] == s[i + l] && dp[i + 1][i + l - 1]) { 32 | dp[i][i + l] = true; 33 | count ++; 34 | continue; 35 | } 36 | 37 | dp[i][i + l] = false; 38 | } 39 | } 40 | 41 | return count; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /chapter 11/566 重塑矩阵.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 566. Reshape the Matrix 3 | 4 | class Solution { 5 | public: 6 | vector> matrixReshape(vector>& nums, int r, int c) { 7 | if (nums.empty()) { 8 | return nums; 9 | } 10 | 11 | int row = nums.size(); 12 | int col = nums[0].size(); 13 | 14 | if (r <= 0 || c <= 0 || row * col != r * c) { 15 | return nums; 16 | } 17 | 18 | 19 | vector > matrix(r, vector (c, 0)); 20 | for (int i = 0; i < row; i++) { 21 | for (int j = 0; j < col; j++) { 22 | int newi = 0; 23 | int newj = 0; 24 | int k = i * col + j + 1; 25 | 26 | if (k % c == 0) { 27 | newi = k / c - 1; 28 | newj = c - 1; 29 | } else { 30 | newi = k / c; 31 | newj = k % c - 1; 32 | } 33 | 34 | matrix[newi][newj] = nums[i][j]; 35 | } 36 | } 37 | 38 | return matrix; 39 | 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /chapter 14/538 把二叉搜索树转化为累加树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 538. Convert BST to Greater Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | void helper(TreeNode* root, int& pred) { 18 | // assert(root != NULL); 19 | 20 | if (root->right != NULL) { 21 | helper(root->right, pred); 22 | } 23 | 24 | root->val += pred; 25 | pred = root->val; 26 | 27 | if (root->left != NULL) { 28 | helper(root->left, pred); 29 | } 30 | 31 | return; 32 | } 33 | 34 | TreeNode* convertBST(TreeNode* root) { 35 | if (root == NULL) { 36 | return NULL; 37 | } 38 | 39 | int pred = 0; 40 | helper(root, pred); 41 | 42 | return root; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /chapter 9/415 字符串相加.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 415. Add Strings 3 | 4 | class Solution { 5 | public: 6 | string addChar(string num1, int ptr1, string num2, int ptr2, int& add) { 7 | int number1 = 0, number2 = 0; 8 | if (0 <= ptr1 && ptr1 < num1.size()) { 9 | number1 = num1[ptr1] - '0'; 10 | } 11 | 12 | if (0 <= ptr2 && ptr2 < num2.size()) { 13 | number2 = num2[ptr2] - '0'; 14 | } 15 | 16 | int res = number1 + number2 + add; 17 | add = res / 10; 18 | 19 | return to_string(res % 10); 20 | } 21 | 22 | 23 | string addStrings(string num1, string num2) { 24 | if (num1.empty()) { 25 | return num2; 26 | } else if (num2.empty()) { 27 | return num1; 28 | } 29 | 30 | int ptr1 = num1.size() - 1; 31 | int ptr2 = num2.size() - 1; 32 | int add = 0; 33 | string sum = ""; 34 | 35 | while (ptr1 >= 0 || ptr2 >= 0 || add > 0) { 36 | sum = addChar(num1, ptr1, num2, ptr2, add) + sum; 37 | ptr1--; 38 | ptr2--; 39 | } 40 | 41 | return sum; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /chapter 14/897 递增顺序搜索树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 897. Increasing Order Search Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | void inorder(TreeNode* root, TreeNode*& tail) { 18 | if (root == NULL) { 19 | return; 20 | } 21 | 22 | inorder(root->left, tail); 23 | root->left = NULL; 24 | tail->right = root; 25 | tail = root; 26 | inorder(root->right, tail); 27 | 28 | tail->right = NULL; 29 | return; 30 | } 31 | 32 | TreeNode* increasingBST(TreeNode* root) { 33 | if (root == NULL) { 34 | return NULL; 35 | } 36 | 37 | TreeNode* prefix = new TreeNode(-1); 38 | TreeNode* tail = prefix; 39 | 40 | inorder(root, tail); 41 | return prefix->right; 42 | 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /chapter 14/653 两数之和4-输入BST.cpp: -------------------------------------------------------------------------------- 1 | // 653. Two Sum IV - Input is a BST 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | bool preorder(TreeNode* root, unordered_set& hash, int target) { 17 | if (root == NULL) { 18 | return false; 19 | } 20 | 21 | if (hash.find(target - root->val) != hash.end()) { 22 | return true; 23 | } 24 | 25 | hash.insert(root->val); 26 | return preorder(root->left, hash, target) || preorder(root->right, hash, target); 27 | 28 | } 29 | 30 | bool findTarget(TreeNode* root, int k) { 31 | unordered_set hash; 32 | 33 | if (root == NULL) { 34 | return false; 35 | } 36 | 37 | bool isExist = preorder(root, hash, k); 38 | return isExist; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /chapter 14/94 二叉树的中序遍历(迭代).cpp: -------------------------------------------------------------------------------- 1 | 2 | // 94. Binary Tree Inorder Traversal 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | vector inorderTraversal(TreeNode* root) { 18 | vector ret; 19 | stack stk; 20 | 21 | if (root == NULL) { 22 | return ret; 23 | } 24 | 25 | TreeNode* ptr = root; 26 | while (ptr != NULL || !stk.empty()) { 27 | while (ptr != NULL) { 28 | stk.push(ptr); 29 | ptr = ptr->left; 30 | } 31 | 32 | if (!stk.empty()) { 33 | ptr = stk.top(); 34 | stk.pop(); 35 | 36 | ret.push_back(ptr->val); 37 | ptr = ptr->right; 38 | } 39 | } 40 | 41 | return ret; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /chapter 11/128 最长连续序列.cpp: -------------------------------------------------------------------------------- 1 | // 128. Longest Consecutive Sequence 2 | 3 | class Solution { 4 | public: 5 | int longestConsecutive(vector& nums) { 6 | int numLen = nums.size(); 7 | int maxLen = 0; 8 | unordered_set hash; 9 | 10 | if (numLen <= 1) { 11 | return numLen; 12 | } 13 | 14 | for (int i = 0; i < numLen; i++) { 15 | hash.insert(nums[i]); 16 | 17 | } 18 | 19 | while (!hash.empty()) { 20 | unordered_set::iterator it = hash.begin(); 21 | int curr = *it; 22 | int len = 0; 23 | 24 | while (it != hash.end()) { 25 | len++; 26 | int val = *it; 27 | hash.erase(val); 28 | it = hash.find(val + 1); 29 | } 30 | 31 | it = hash.find(curr - 1); 32 | while (it != hash.end()) { 33 | len++; 34 | int val = *it; 35 | hash.erase(val); 36 | it = hash.find(val - 1); 37 | } 38 | 39 | maxLen = max(maxLen, len); 40 | } 41 | 42 | return maxLen; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /chapter 7/188 买卖股票的最佳时机4.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 188. Best Time to Buy and Sell Stock IV 3 | 4 | class Solution { 5 | public: 6 | int maxProfitUnlimited(vector& prices) { 7 | int maxProfit = 0; 8 | int len = prices.size(); 9 | 10 | for (int i = 1; i < len; i++) { 11 | if (prices[i] > prices[i - 1]) { 12 | maxProfit += (prices[i] - prices[i - 1]); 13 | } 14 | } 15 | 16 | return maxProfit; 17 | } 18 | 19 | int maxProfit(int k, vector& prices) { 20 | int len = prices.size(); 21 | 22 | if (prices.empty()) { 23 | return 0; 24 | } 25 | 26 | if (k >= len) { 27 | return maxProfitUnlimited(prices); 28 | } 29 | 30 | vector buy(k + 1, 0); 31 | vector sell(k + 1, 0); 32 | 33 | buy[0][1] = -prices[0]; 34 | 35 | for (int i = 1; i < len; i++) { 36 | for (int j = 1; j <= k; j++) { 37 | buy[j] = max(buy[j], sell[j - 1] - prices[i]); 38 | sell[j] = max(sell[j], buy[j] + prices[i]); 39 | } 40 | } 41 | 42 | return sell[k]; 43 | 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /chapter 16/684 冗余连接.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 684. Redundant Connection 3 | 4 | class UF { 5 | private: 6 | vector id; 7 | public: 8 | UF(int n) : id(n) { 9 | iota(id.begin(), id.end(), 0); 10 | } 11 | 12 | int find(int p) { 13 | while (p != id[p]) { 14 | id[p] = id[id[p]]; 15 | p = id[p]; 16 | } 17 | return p; 18 | } 19 | 20 | void connect(int x, int y) { 21 | id[find(x)] = id[find(y)]; 22 | return; 23 | } 24 | 25 | bool isConnected(int x, int y) { 26 | return find(x) == find(y); 27 | } 28 | }; 29 | 30 | 31 | class Solution { 32 | public: 33 | vector findRedundantConnection(vector>& edges) { 34 | int len = edges.size(); 35 | UF uf(len + 1); 36 | 37 | if (edges.empty() || len == 1) { 38 | return vector {-1, -1}; 39 | } 40 | 41 | for (int i = 0; i < len ; i++) { 42 | int u = edges[i][0]; 43 | int v = edges[i][1]; 44 | if (uf.isConnected(u, v)) { 45 | return edges[i]; 46 | } else { 47 | uf.connect(u, v); 48 | } 49 | } 50 | 51 | return vector {-1, -1}; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /chapter 6/46 全排列.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 46. Permutations 3 | 4 | class Solution { 5 | public: 6 | void dfs (vector& nums, int depth, vector& path, 7 | vector& used, vector >& res) { 8 | 9 | int len = nums.size(); 10 | if (nums.empty()) { 11 | return; 12 | } 13 | 14 | if (depth == len) { 15 | res.push_back(path); 16 | return; 17 | } 18 | 19 | for (int i = 0; i < len; i++) { 20 | if (used[i]) { 21 | continue; 22 | } 23 | 24 | path.push_back(nums[i]); 25 | used[i] = true; 26 | dfs(nums, depth + 1, path, used, res); 27 | path.pop_back(); 28 | used[i] = false; 29 | } 30 | 31 | return; 32 | } 33 | 34 | vector> permute(vector& nums) { 35 | vector > res; 36 | int len = nums.size(); 37 | 38 | if (nums.empty()) { 39 | return res; 40 | } 41 | 42 | vector used(len, false); 43 | vector path; 44 | 45 | dfs(nums, 0, path, used, res); 46 | return res; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /chapter 11/239 滑动窗口最大值.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 239. Sliding Window Maximum 3 | 4 | class Solution { 5 | public: 6 | vector maxSlidingWindow(vector& nums, int k) { 7 | vector maxVal; 8 | deque loc; 9 | 10 | if (nums.empty() || k <= 0) { 11 | return maxVal; 12 | } 13 | 14 | for (int i = 0; i < k; i++) { 15 | if (i >= len) { 16 | break; 17 | } 18 | 19 | while (!loc.empty() && nums[loc.back()] < nums[i]) { 20 | loc.pop_back(); 21 | } 22 | 23 | loc.push_back(i); 24 | } 25 | 26 | if (k >= len) { 27 | maxVal.push_back(nums[loc.front()]); 28 | return maxVal; 29 | } 30 | 31 | for (int i = k; i < len; i++) { 32 | if (loc.front() == i - k) { 33 | loc.pop_front(); 34 | } 35 | 36 | while (!loc.empty() && nums[loc.back()] < nums[i]) { 37 | loc.pop_back(); 38 | } 39 | loc.push_back(i); 40 | 41 | maxVal.push_back(nums[loc.front()]); 42 | } 43 | 44 | return maxVal; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /chapter 13/328 奇偶链表.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 328. Odd Even Linked List 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode() : val(0), next(nullptr) {} 10 | * ListNode(int x) : val(x), next(nullptr) {} 11 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | ListNode* oddEvenList(ListNode* head) { 17 | if (head == nullptr || head->next == nullptr) { 18 | return head; 19 | } 20 | 21 | ListNode* oddhead = head, *oddtail = head; 22 | ListNode* evenhead = head->next, *eventail = head->next; 23 | ListNode* ptr = eventail->next; 24 | 25 | int k = 3; 26 | while (ptr != nullptr) { 27 | ListNode* tmp = ptr; 28 | ptr = ptr->next; 29 | if (k % 2 != 0) { 30 | oddtail->next = tmp; 31 | oddtail = oddtail->next; 32 | } else { 33 | eventail->next = tmp; 34 | eventail = eventail->next; 35 | } 36 | k++; 37 | } 38 | 39 | oddtail->next = evenhead; 40 | eventail->next = nullptr; 41 | return oddhead; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /chapter 13/21 合并两个有序链表.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 21. Merge Two Sorted Lists 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode() : val(0), next(nullptr) {} 10 | * ListNode(int x) : val(x), next(nullptr) {} 11 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { 17 | if (l1 == nullptr) { 18 | return l2; 19 | } else if (l2 == nullptr) { 20 | return l1; 21 | } 22 | 23 | ListNode* dummy = new ListNode(); 24 | ListNode* tail = dummy; 25 | while (l1 != nullptr && l2 != nullptr) { 26 | ListNode* tmp = nullptr; 27 | if (l1->val < l2->val) { 28 | tmp = l1; 29 | l1 = l1->next; 30 | } else { 31 | tmp = l2; 32 | l2 = l2->next; 33 | } 34 | tail->next = tmp; 35 | tail = tail->next; 36 | } 37 | 38 | if (l1 == nullptr) { 39 | tail->next = l2; 40 | } else { 41 | tail->next = l1; 42 | } 43 | 44 | return dummy->next; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /chapter 14/144 二叉树的前序遍历(迭代).cpp: -------------------------------------------------------------------------------- 1 | 2 | // 144. Binary Tree Preorder Traversal 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | vector preorderTraversal(TreeNode* root) { 18 | vector tranvers; 19 | stack helper; 20 | 21 | if (root == NULL) { 22 | return tranvers; 23 | } 24 | 25 | helper.push(root); 26 | 27 | while (!helper.empty()) { 28 | TreeNode* curr = helper.top(); 29 | helper.pop(); 30 | 31 | tranvers.push_back(curr->val); 32 | 33 | if (curr->right != NULL) { 34 | helper.push(curr->right); 35 | } 36 | 37 | if (curr->left != NULL) { 38 | helper.push(curr->left); 39 | } 40 | } 41 | 42 | return tranvers; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /chapter 9/382 链表随机节点.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 382. Linked List Random Node 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode() : val(0), next(nullptr) {} 10 | * ListNode(int x) : val(x), next(nullptr) {} 11 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 12 | * }; 13 | */ 14 | class Solution { 15 | private: 16 | ListNode* headptr; 17 | public: 18 | /** @param head The linked list's head. 19 | Note that the head is guaranteed to be not null, so it contains at least one node. */ 20 | Solution(ListNode* head) { 21 | headptr = head; 22 | } 23 | 24 | /** Returns a random node's value. */ 25 | int getRandom() { 26 | int count = 2; 27 | int ret = headptr->val; 28 | ListNode* ptr = headptr->next; 29 | 30 | while (ptr != NULL) { 31 | if (rand() % count == 0) { 32 | ret = ptr->val; 33 | } 34 | count ++; 35 | ptr = ptr->next; 36 | } 37 | 38 | return ret; 39 | } 40 | }; 41 | 42 | /** 43 | * Your Solution object will be instantiated and called as such: 44 | * Solution* obj = new Solution(head); 45 | * int param_1 = obj->getRandom(); 46 | */ 47 | -------------------------------------------------------------------------------- /chapter 16/146 LRU 缓存.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 146. LRU Cache 3 | 4 | class LRUCache { 5 | private: 6 | list > cache; 7 | unordered_map >::iterator> hash; 8 | int maxSize; 9 | public: 10 | LRUCache(int capacity) : maxSize(capacity) { 11 | 12 | } 13 | 14 | int get(int key) { 15 | auto it = hash.find(key); 16 | if (it == hash.end()) { 17 | return -1; 18 | } 19 | cache.splice(cache.begin(), cache, it->second); 20 | return (*(it->second)).second; 21 | } 22 | 23 | void put(int key, int value) { 24 | auto it = hash.find(key); 25 | if (it != hash.end()) { 26 | (*(it->second)).second = value; 27 | cache.splice(cache.begin(), cache, it->second); 28 | return; 29 | } 30 | 31 | cache.insert(cache.begin(), make_pair(key, value)); 32 | hash[key] = cache.begin(); 33 | 34 | if (cache.size() > maxSize) { 35 | hash.erase(cache.back().first); 36 | cache.pop_back(); 37 | } 38 | return; 39 | } 40 | }; 41 | 42 | /** 43 | * Your LRUCache object will be instantiated and called as such: 44 | * LRUCache* obj = new LRUCache(capacity); 45 | * int param_1 = obj->get(key); 46 | * obj->put(key,value); 47 | */ 48 | -------------------------------------------------------------------------------- /chapter 13/19 删除链表倒数第n个节点.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 19. Remove Nth Node From End of List 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode() : val(0), next(nullptr) {} 10 | * ListNode(int x) : val(x), next(nullptr) {} 11 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | ListNode* removeNthFromEnd(ListNode* head, int n) { 17 | ListNode* ptr = head; 18 | int i = 0; 19 | for (i = 0; i < n; i++) { 20 | if (ptr == nullptr) { 21 | break; 22 | } 23 | ptr = ptr->next; 24 | } 25 | 26 | if (ptr == nullptr) { 27 | if (i < n - 1) { 28 | return head; 29 | } else { 30 | ListNode* tmp = head; 31 | head = head->next; 32 | delete tmp; 33 | return head; 34 | } 35 | } 36 | 37 | ListNode* prevDel = head; 38 | while (ptr->next != nullptr) { 39 | prevDel = prevDel->next; 40 | ptr = ptr->next; 41 | } 42 | 43 | ListNode* tmp = prevDel->next; 44 | prevDel->next = tmp->next; 45 | delete tmp; 46 | return head; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /chapter 7/474 零和一.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 474. Ones and Zeroes 3 | 4 | class Solution { 5 | public: 6 | pair count(string str) { 7 | int num0 = 0; 8 | int num1 = 0; 9 | 10 | int len = str.size(); 11 | for (int i = 0; i < len; i++) { 12 | if (str[i] == '0') { 13 | num0 ++; 14 | } else if (str[i] == '1') { 15 | num1 ++; 16 | } 17 | } 18 | 19 | return make_pair(num0, num1); 20 | } 21 | 22 | int findMaxForm(vector& strs, int m, int n) { 23 | if (strs.empty()) { 24 | return 0; 25 | } 26 | 27 | // assert(m > 0 && n > 0); 28 | 29 | int len = strs.size(); 30 | vector > dp(m + 1, vector (n + 1, 0)); 31 | dp[0][0] = 0; 32 | for (int k = 1; k <= len; k++) { 33 | pair tmp = count(strs[k - 1]); 34 | int num0 = tmp.first; 35 | int num1 = tmp.second; 36 | 37 | for (int j = n; j >= num1; j--) { 38 | for (int i = m; i >= num0; i--) { 39 | dp[i][j] = max(dp[i][j], dp[i - num0][j - num1] + 1) ; 40 | } 41 | } 42 | } 43 | 44 | return dp[m][n]; 45 | 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /chapter 14/513 找树左下角的值.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 513. Find Bottom Left Tree Value 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | int findBottomLeftValue(TreeNode* root) { 18 | // assert(root != NULL); 19 | 20 | queue que; 21 | que.push(root); 22 | 23 | int leftVal = 0; 24 | 25 | while (!que.empty()) { 26 | int tos = que.size(); 27 | leftVal = que.front()->val; 28 | 29 | while (tos > 0) { 30 | tos--; 31 | TreeNode* tmp = que.front(); 32 | que.pop(); 33 | 34 | if (tmp->left != NULL) { 35 | que.push(tmp->left); 36 | } 37 | 38 | if (tmp->right != NULL) { 39 | que.push(tmp->right); 40 | } 41 | } 42 | } 43 | 44 | return leftVal; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /chapter 12/5 最长回文子串.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 5. Longest Palindromic Substring 3 | 4 | class Solution { 5 | public: 6 | string longestPalindrome(string s) { 7 | int len = s.size(); 8 | string retStr = ""; 9 | if (s.empty()) { 10 | return retStr; 11 | } 12 | 13 | if (len == 1) { 14 | return (retStr + s[0]); 15 | } 16 | 17 | vector > dp(len, vector(len, false)); 18 | int maxLen = 1; 19 | pair palStr(0, 0); 20 | 21 | for (int i = 0; i < len - 1; i++) { 22 | dp[i][i] = true; 23 | if (s[i] == s[i + 1]) { 24 | dp[i][i + 1] = true; 25 | maxLen = 2; 26 | palStr.first = i; 27 | palStr.second = i + 1; 28 | } 29 | } 30 | dp[len - 1][len - 1] = true; 31 | 32 | for (int l = 2; l < len; l++) { 33 | for (int i = 0; i < len - l; i++) { 34 | dp[i][i + l] = ((s[i] == s[i + l]) && dp[i + 1][i + l - 1]); 35 | if (dp[i][i + l] && l + 1 > maxLen) { 36 | maxLen = l + 1; 37 | palStr.first = i; 38 | palStr.second = i + l; 39 | } 40 | } 41 | } 42 | 43 | return s.substr(palStr.first, maxLen); 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /chapter 7/494 目标和.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 494. Target Sum 3 | 4 | class Solution { 5 | public: 6 | int findTargetSumWays(vector& nums, int target) { 7 | int len = nums.size(); 8 | 9 | if (nums.empty()) { 10 | return 0; 11 | } 12 | 13 | // assert(nums[i] >= 0); 14 | int sum = accumulate(nums.begin(), nums.end(), 0); 15 | if (target > sum || target < -sum) { 16 | return 0; 17 | } 18 | 19 | 20 | int offset = sum; 21 | vector > dp(len, vector (2 * sum + 1, 0)); 22 | 23 | dp[0][nums[0] + offset] += 1; 24 | dp[0][- nums[0] + offset] += 1; 25 | 26 | for (int i = 1; i < len; i++) { 27 | for (int j = -sum; j <= sum; j++) { 28 | if (nums[i] == 0) { 29 | dp[i][j + offset] = dp[i - 1][j + offset] * 2; 30 | } else { 31 | if (j - nums[i] >= -sum) { 32 | dp[i][j + offset] += dp[i - 1][j - nums[i] + offset]; 33 | } 34 | 35 | if (j + nums[i] <= sum) { 36 | dp[i][j + offset] += dp[i - 1][j + nums[i] + offset]; 37 | } 38 | } 39 | } 40 | } 41 | 42 | return dp[len - 1][target + offset]; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /chapter 11/697 数组的度.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 697. Degree of an Array 3 | 4 | class Solution { 5 | public: 6 | int findShortestSubArray(vector& nums) { 7 | int len = nums.size(); 8 | unordered_map > hash; 9 | 10 | if (len <= 1) { 11 | return len; 12 | } 13 | 14 | for (int i = 0; i < len; i++) { 15 | if (hash.find(nums[i]) == hash.end()) { 16 | vector tmp(3, 0); 17 | tmp[0] = 1; 18 | tmp[1] = i; 19 | tmp[2] = i; 20 | 21 | hash[nums[i]] = tmp; 22 | } else { 23 | hash[nums[i]][0] ++; 24 | hash[nums[i]][2] = i; 25 | } 26 | } 27 | 28 | int maxd = 0; 29 | int shortestLen = 0; 30 | unordered_map >::iterator it; 31 | 32 | for (it = hash.begin(); it != hash.end(); it++) { 33 | bool isLessLen = (it->second)[0] == maxd && ((it->second)[2] - (it->second)[1] + 1 ) < shortestLen; 34 | if ((it->second)[0] > maxd || isLessLen) 35 | { 36 | maxd = (it->second)[0]; 37 | shortestLen = (it->second)[2] - (it->second)[1] + 1; 38 | } 39 | 40 | } 41 | 42 | return shortestLen; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /chapter 11/149 直线上最多的点数.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 149. Max Points on a Line 3 | 4 | class Solution { 5 | public: 6 | int maxPoints(vector>& points) { 7 | int len = points.size(); 8 | int maxNum = 0; 9 | map, int> hash; 10 | 11 | if (points.empty() || len <= 2) { 12 | return len; 13 | } 14 | 15 | for (int i = 0; i < len; i++) { 16 | hash.clear(); 17 | 18 | for (int j = i + 1; j < len; j++) { 19 | int dx = points[i][0] - points[j][0]; 20 | int dy = points[i][1] - points[j][1]; 21 | int g = gcd(dx, dy); 22 | 23 | if (hash.find({dx/g, dy/g}) != hash.end()) { 24 | hash[{dx/g, dy/g}] ++; 25 | maxNum = max(maxNum, hash[{dx/g, dy/g}]); 26 | continue; 27 | } 28 | 29 | if (hash.find({-dx/g, -dy/g}) != hash.end()) { 30 | hash[{-dx/g, -dy/g}] ++; 31 | maxNum = max(maxNum, hash[{-dx/g, -dy/g}]); 32 | continue; 33 | } 34 | 35 | hash[{dx/g, dy/g}] = 2; 36 | maxNum = max(maxNum, hash[{dx/g, dy/g}]); 37 | 38 | } 39 | } 40 | 41 | return maxNum; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /chapter 7/1143 最长公共子序列.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 1143. Longest Common Subsequence 3 | 4 | class Solution { 5 | public: 6 | int longestCommonSubsequence(string text1, string text2) { 7 | int len1 = text1.size(); 8 | int len2 = text2.size(); 9 | vector > dp(len1, vector (len2, 0)); 10 | 11 | if (text1.empty() || text2.empty()) { 12 | return 0; 13 | } 14 | 15 | if (text1[0] == text2[0]) { 16 | dp[0][0] = 1; 17 | } else { 18 | dp[0][0] = 0; 19 | } 20 | 21 | for (int j = 1; j < len2; j++) { 22 | if (text1[0] == text2[j] || dp[0][j - 1] == 1) { 23 | dp[0][j] = 1; 24 | } 25 | } 26 | 27 | for (int i = 1; i < len1; i++) { 28 | if (text1[i] == text2[0] || dp[i - 1][0] == 1) { 29 | dp[i][0] = 1; 30 | } 31 | } 32 | 33 | for (int i = 1; i < len1; i++) { 34 | for (int j = 1; j < len2; j++) { 35 | if (text1[i] == text2[j]) { 36 | dp[i][j] = dp[i - 1][j - 1] + 1; 37 | } else { 38 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 39 | } 40 | } 41 | 42 | } 43 | 44 | return dp[len1 - 1][len2 - 1]; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /chapter 6/40 全组合2.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 40. Combination Sum II 3 | 4 | class Solution { 5 | public: 6 | void dfs(vector& candidates, int pos, int target, vector& path, 7 | vector >& res) { 8 | // assert... 9 | 10 | int len = candidates.size(); 11 | if (target == 0) { 12 | res.push_back(path); 13 | return; 14 | } 15 | 16 | for (int i = pos; i < len; i++) { 17 | if (candidates[i] > target) { 18 | break; 19 | } 20 | 21 | if (i > pos && candidates[i] == candidates[i - 1] ) { 22 | continue; 23 | } 24 | 25 | path.push_back(candidates[i]); 26 | 27 | dfs(candidates, i + 1, target - candidates[i], path, res); 28 | 29 | path.pop_back(); 30 | } 31 | 32 | return; 33 | } 34 | 35 | vector> combinationSum2(vector& candidates, int target) { 36 | int len = candidates.size(); 37 | vector path; 38 | vector > res; 39 | 40 | if (candidates.empty()) { 41 | return res; 42 | } 43 | 44 | sort(candidates.begin(), candidates.end()); 45 | dfs(candidates, 0, target, path, res); 46 | 47 | return res; 48 | 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /chapter 14/236 二叉树的最近公共祖先.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 236. Lowest Common Ancestor of a Binary Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | TreeNode* helper(TreeNode* root, TreeNode* p, TreeNode* q) { 16 | // assert(p != NULL && q != NULL); 17 | 18 | if (root == NULL) { 19 | return NULL; 20 | } 21 | 22 | if (root == p || root == q) { 23 | return root; 24 | } 25 | 26 | TreeNode* lptr = helper(root->left, p, q); 27 | TreeNode* rptr = helper(root->right, p, q); 28 | 29 | if (lptr == NULL && rptr == NULL) { 30 | return NULL; // throw error 31 | } 32 | 33 | if (lptr != NULL && rptr != NULL) { 34 | return root; 35 | } 36 | 37 | if (lptr == NULL) { 38 | return rptr; 39 | } else { 40 | return lptr; 41 | } 42 | 43 | } 44 | 45 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 46 | if (root == NULL || p == NULL || q == NULL) { 47 | return NULL; 48 | } 49 | 50 | return helper(root, p, q); 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /chapter 11/23 合并K个升序链表.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 23. Merge k Sorted Lists 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode() : val(0), next(nullptr) {} 10 | * ListNode(int x) : val(x), next(nullptr) {} 11 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | struct cmp { 17 | bool operator() (ListNode* node1, ListNode* node2) { 18 | return node1->val > node2->val; 19 | } 20 | }; 21 | 22 | ListNode* mergeKLists(vector& lists) { 23 | int len = lists.size(); 24 | priority_queue, cmp> que; 25 | 26 | if (lists.empty()) { 27 | return NULL; 28 | } 29 | 30 | for (int i = 0; i < len; i++) { 31 | if (lists[i] != NULL) { 32 | que.push(lists[i]); 33 | } 34 | } 35 | 36 | ListNode* root = new ListNode(0); 37 | ListNode* tail = root; 38 | 39 | while (!que.empty()) { 40 | tail->next = que.top(); 41 | tail = tail->next; 42 | que.pop(); 43 | 44 | if (tail->next != NULL) { 45 | que.push(tail->next); 46 | } 47 | } 48 | 49 | return root->next; 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /chapter 6/547 省份数量.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 547. Number of Provinces 3 | 4 | class Solution { 5 | public: 6 | void dfsTranvers(vector>& isConnected, int i, int j) { 7 | // assert(isConnected[i][j] == 1); 8 | isConnected[i][j] = 0; 9 | vector direction {-1, 0, 1, 0, -1}; 10 | for (int k = 0; k <= direction.size() - 2; k++) { 11 | int x = i + direction[k]; 12 | int y = j + direction[k + 1]; 13 | int row = isConnected.size(); 14 | int col = isConnected[0].size(); 15 | 16 | if (0 <= x && x < row && 0 <= y && y < col && isConnected[x][y] == 1) { 17 | dfsTranvers(isConnected, x, y); 18 | } 19 | } 20 | 21 | return; 22 | } 23 | 24 | int findCircleNum(vector>& isConnected) { 25 | if (isConnected.empty()) { 26 | return 0; 27 | } 28 | 29 | int row = isConnected.size(); 30 | int col = isConnected[0].size(); 31 | int count = 0; 32 | for (int i = 0; i < row; i++) { 33 | for (int j = 0; j < col; j++) { 34 | if (isConnected[i][j] == 0) { 35 | continue; 36 | } 37 | 38 | count++; 39 | dfsTranvers(isConnected, i, j); 40 | } 41 | } 42 | 43 | return count; 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /chapter 7/376 最长摇摆子序列.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 376. Wiggle Subsequence 3 | 4 | class Solution { 5 | public: 6 | 7 | // DP, Time: O(n^2) 8 | int wiggleMaxLength(vector& nums) { 9 | int len = nums.size(); 10 | 11 | if (nums.empty()) { 12 | return 0; 13 | } 14 | 15 | if (len == 1) { 16 | return 1; 17 | } 18 | 19 | vector pdp(len, 1); // positive dp table: list[i - 1] < list[i] in the wiggle list. 20 | vector ndp(len, 1); // negative dp table: list[i - 1] > list[i] in the wiggle list. 21 | 22 | if (nums[1] > nums[0]) { 23 | pdp[1] = 2; 24 | } else if (nums[1] < nums[0]) { 25 | ndp[1] = 2; 26 | } else { 27 | pdp[1] = 1; 28 | ndp[1] = 1; 29 | } 30 | 31 | int maxLen = max(max(pdp[0], ndp[0]), max(pdp[1], ndp[1])); 32 | for (int i = 2; i < len; i++) { 33 | for (int j = i - 1; j >= 0; j--) { 34 | if (nums[j] < nums[i]) { 35 | pdp[i] = max(pdp[i], ndp[j] + 1); 36 | } 37 | 38 | if (nums[j] > nums[i]) { 39 | ndp[i] = max(ndp[i], pdp[j] + 1); 40 | } 41 | } 42 | 43 | maxLen = max(maxLen, max(pdp[i], ndp[i])); 44 | } 45 | 46 | return maxLen; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /chapter 14/437 路径总和3.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 437. Path Sum III 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | int dfs(TreeNode* root, int targetSum) { 18 | int total = 0; 19 | if (root == NULL) { 20 | // assert(targetSum != 0); 21 | return 0; 22 | } 23 | 24 | 25 | if (root->val == targetSum) { 26 | total = 1 + dfs(root->left, 0) + dfs(root->right, 0); 27 | return total; 28 | } 29 | 30 | // root->val != targetSum 31 | int add = targetSum - root->val; 32 | return dfs(root->left, add) + dfs(root->right, add); 33 | 34 | } 35 | 36 | int pathSum(TreeNode* root, int targetSum) { 37 | if (root == NULL) { 38 | return 0; 39 | } 40 | 41 | int inleft = pathSum(root->left, targetSum); 42 | int inright = pathSum(root->right, targetSum); 43 | int incurr = dfs(root, targetSum); 44 | 45 | int total = inleft + inright + incurr; 46 | return total; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /chapter 14/145 二叉树的后序遍历(迭代).cpp: -------------------------------------------------------------------------------- 1 | // 145. Binary Tree Postorder Traversal 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | vector postorderTraversal(TreeNode* root) { 17 | vector ret; 18 | stack > stk; 19 | 20 | if (root == NULL) { 21 | return ret; 22 | } 23 | 24 | TreeNode* ptr = root; 25 | while (ptr != NULL || !stk.empty()) { 26 | while (ptr != NULL) { 27 | stk.push({ptr, false}); 28 | ptr = ptr->left; 29 | } 30 | 31 | if (!stk.empty()) { 32 | ptr = (stk.top()).first; 33 | } 34 | 35 | if (ptr->right == NULL || (stk.top()).second) { 36 | ret.push_back(ptr->val); 37 | stk.pop(); 38 | ptr = NULL; 39 | } else { 40 | (stk.top()).second = true; 41 | ptr = ptr->right; 42 | } 43 | 44 | } 45 | 46 | return ret; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /chapter 14/543 二叉树的直径.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 543. Diameter of Binary Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | void getDiameterAndDepth(TreeNode* root, int& diameter, int& depth) { 18 | if (root == NULL) { 19 | diameter = 0; 20 | depth = 0; 21 | return; 22 | } 23 | 24 | int leftDiameter = 0, rightDiameter = 0; 25 | int leftDepth = 0, rightDepth = 0; 26 | 27 | getDiameterAndDepth(root->left, leftDiameter, leftDepth); 28 | getDiameterAndDepth(root->right, rightDiameter, rightDepth); 29 | 30 | // Note: diameter is the num of edges from one node to another node, 31 | // not the num of nodes. 32 | diameter = max(leftDepth + rightDepth, max(leftDiameter, rightDiameter)); 33 | depth = max(leftDepth, rightDepth) + 1; 34 | return; 35 | } 36 | 37 | int diameterOfBinaryTree(TreeNode* root) { 38 | int diameter = 0; 39 | int depth = 0; 40 | 41 | getDiameterAndDepth(root, diameter, depth); 42 | return diameter; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /chapter 11/155 最小栈.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 155. Min Stack 3 | 4 | class MinStack { 5 | 6 | stack stk, minStk; 7 | 8 | public: 9 | /** initialize your data structure here. */ 10 | MinStack() { 11 | 12 | } 13 | 14 | void push(int val) { 15 | stk.push(val); 16 | 17 | if (minStk.empty()) { 18 | minStk.push(val); 19 | return; 20 | } 21 | 22 | 23 | int minVal = minStk.top(); 24 | if (val < minVal) { 25 | minStk.push(val); 26 | } else { 27 | minStk.push(minVal); 28 | } 29 | 30 | return; 31 | 32 | } 33 | 34 | 35 | void pop() { 36 | if (!stk.empty()) { 37 | stk.pop(); 38 | minStk.pop(); 39 | return; 40 | } 41 | 42 | // throw error 43 | return; 44 | } 45 | 46 | int top() { 47 | if (!stk.empty()) { 48 | return stk.top(); 49 | } 50 | 51 | // throw error 52 | return INT_MIN; 53 | } 54 | 55 | int getMin() { 56 | if (!minStk.empty()) { 57 | return minStk.top(); 58 | } 59 | 60 | // throw error 61 | return INT_MIN; 62 | } 63 | }; 64 | 65 | /** 66 | * Your MinStack object will be instantiated and called as such: 67 | * MinStack* obj = new MinStack(); 68 | * obj->push(val); 69 | * obj->pop(); 70 | * int param_3 = obj->top(); 71 | * int param_4 = obj->getMin(); 72 | */ 73 | -------------------------------------------------------------------------------- /chapter 8/932 漂亮数组.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 932. Beautiful Array 3 | 4 | class Solution { 5 | public: 6 | vector getBeautiful(int n, unordered_map >& hash) { 7 | vector ret; 8 | if (hash.find(n) != hash.end()) { 9 | return hash[n]; 10 | } 11 | 12 | if (n < 3) { 13 | for (int i = 1; i <= n; i++) { 14 | ret.push_back(i); 15 | } 16 | hash[n] = ret; 17 | return ret; 18 | } 19 | 20 | int n1 = (n + 1) / 2; 21 | int n2 = n / 2; 22 | 23 | vector ret1 = getBeautiful(n1, hash); 24 | vector ret2 = getBeautiful(n2, hash); 25 | 26 | for (int i = 0; i < ret1.size(); i++) { 27 | ret1[i] = 2 * ret1[i] - 1; 28 | } 29 | 30 | for (int i = 0; i < ret2.size(); i++) { 31 | ret2[i] = 2 * ret2[i]; 32 | } 33 | 34 | ret.insert(ret.end(), ret1.begin(), ret1.end()); 35 | ret.insert(ret.end(), ret2.begin(), ret2.end()); 36 | return ret; 37 | } 38 | 39 | vector beautifulArray(int N) { 40 | vector ret; 41 | if (N < 3) { 42 | for (int i = 1; i <= N; i++) { 43 | ret.push_back(i); 44 | } 45 | return ret; 46 | } 47 | 48 | unordered_map > hash; 49 | ret = getBeautiful(N, hash); 50 | return ret; 51 | } 52 | }; 53 | 54 | -------------------------------------------------------------------------------- /chapter 14/105 从前序和中序遍历序列构造二叉树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 105. Construct Binary Tree from Preorder and Inorder Traversal 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | TreeNode* buildTree(vector& preorder, vector& inorder) { 18 | if (preorder.empty() || inorder.empty()) { 19 | return NULL; 20 | } 21 | 22 | int rootVal = preorder[0]; 23 | int ptr = 0; 24 | for (ptr = 0; ptr < inorder.size(); ptr++) { 25 | if (inorder[ptr] == rootVal) { 26 | break; 27 | } 28 | } 29 | 30 | TreeNode* root = new TreeNode(rootVal); 31 | 32 | vector leftInorder(inorder.begin(), inorder.begin() + ptr); 33 | vector rightInorder(inorder.begin() + ptr + 1, inorder.end()); 34 | 35 | vector leftPreorder(preorder.begin() + 1, preorder.begin() + 1 + ptr); 36 | vector rightPreorder(preorder.begin() + ptr + 1, preorder.end()); 37 | 38 | root->left = buildTree(leftPreorder, leftInorder); 39 | root->right = buildTree(rightPreorder, rightInorder); 40 | return root; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /chapter 14/110 平衡二叉树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 110. Balanced Binary Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | bool getBalanceAndDepth(TreeNode* root, int& depth) { 18 | if (root == NULL) { 19 | depth = 0; 20 | return true; 21 | } 22 | 23 | int leftDepth = 0; 24 | bool isLeftBalanced = getBalanceAndDepth(root->left, leftDepth); 25 | 26 | if (!isLeftBalanced) { 27 | depth = -1; 28 | return false; 29 | } 30 | 31 | int rightDepth = 0; 32 | bool isRightBalanced = getBalanceAndDepth(root->right, rightDepth); 33 | if (!isRightBalanced) { 34 | depth = -1; 35 | return false; 36 | } 37 | 38 | if (abs(leftDepth - rightDepth) <= 1) { 39 | depth = max(leftDepth, rightDepth) + 1; 40 | return true; 41 | } else { 42 | depth = -1; 43 | return false; 44 | } 45 | 46 | } 47 | 48 | bool isBalanced(TreeNode* root) { 49 | int depth = 0; 50 | return getBalanceAndDepth(root, depth); 51 | 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /chapter 14/889 根据前序和后序遍历序列构造二叉树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 889. Construct Binary Tree from Preorder and Postorder Traversal 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | TreeNode* constructFromPrePost(vector& pre, vector& post) { 16 | if (pre.empty() || post.empty()) { 17 | return NULL; 18 | } 19 | 20 | // assert valid input... 21 | int preLen = pre.size(); 22 | int postLen = post.size(); 23 | TreeNode* ptr = new TreeNode(pre[0]); 24 | 25 | if (preLen == 1) { 26 | return ptr; 27 | } 28 | 29 | int postVal = post[postLen - 2]; 30 | int curr = 1; 31 | for (curr = 1; curr < preLen; curr++) { 32 | if (pre[curr] == postVal) { 33 | break; 34 | } 35 | } 36 | 37 | vector leftPre(pre.begin() + 1, pre.begin() + curr); 38 | vector rightPre(pre.begin() + curr, pre.end()); 39 | vector leftPost(post.begin(), post.begin() + leftPre.size()); 40 | vector rightPost(post.begin() + leftPre.size(), post.end() - 1); 41 | 42 | ptr->left = constructFromPrePost(leftPre, leftPost); 43 | ptr->right = constructFromPrePost(rightPre, rightPost); 44 | 45 | return ptr; 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /chapter 13/234 回文链表.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 234. Palindrome Linked List 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode() : val(0), next(nullptr) {} 10 | * ListNode(int x) : val(x), next(nullptr) {} 11 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | ListNode* reverse(ListNode* head) { 17 | ListNode* rhead = nullptr, *ptr = head; 18 | while (ptr != nullptr) { 19 | ListNode* tmp = ptr; 20 | ptr = ptr->next; 21 | tmp->next = rhead; 22 | rhead = tmp; 23 | } 24 | return rhead; 25 | } 26 | 27 | bool isPalindrome(ListNode* head) { 28 | if (head == nullptr) { 29 | return false; 30 | } 31 | 32 | if (head->next == nullptr) { 33 | return true; 34 | } 35 | 36 | ListNode* fast = head, *slow = head; 37 | while (fast->next != nullptr && (fast->next)->next != nullptr) { 38 | slow = slow->next; 39 | fast = (fast->next)->next; 40 | } 41 | 42 | ListNode* rhead = reverse(slow->next); 43 | ListNode* l1 = head, *l2 = rhead; 44 | while (l2 != nullptr) { 45 | if (l1->val != l2->val) { 46 | return false; 47 | } 48 | l1 = l1->next; 49 | l2 = l2->next; 50 | } 51 | 52 | slow->next = reverse(rhead); 53 | return true; 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /chapter 14/572 另一棵树的子树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 572. Subtree of Another Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | bool isRootSubtree(TreeNode* s, TreeNode* t) { 18 | if (s== NULL && t == NULL) { 19 | return true; 20 | } 21 | 22 | if (s == NULL || t == NULL) { 23 | return false; 24 | } 25 | 26 | // assert(s != NULL && t != NULL); 27 | if (s->val != t->val) { 28 | return false; 29 | } 30 | 31 | return isRootSubtree(s->left, t->left) && isRootSubtree(s->right, t->right); 32 | } 33 | 34 | bool isSubtree(TreeNode* s, TreeNode* t) { 35 | if (t == NULL) { 36 | return true; 37 | } 38 | 39 | // assert(t != NULL); 40 | if (s == NULL) { 41 | return false; 42 | } 43 | 44 | // assert(s != NULL && t != NULL); 45 | if (s->val == t->val) { 46 | return isRootSubtree(s, t) || isSubtree(s->left, t) || isSubtree(s->right, t); 47 | } else { 48 | return isSubtree(s->left, t) || isSubtree(s->right, t); 49 | } 50 | 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /chapter 16/380 常数时间插入删除和获取随机元素.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 380. Insert Delete GetRandom O(1) 3 | 4 | class RandomizedSet { 5 | private: 6 | vector number; 7 | unordered_map hash; 8 | public: 9 | /** Initialize your data structure here. */ 10 | RandomizedSet() { 11 | 12 | } 13 | 14 | /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ 15 | bool insert(int val) { 16 | if (hash.find(val) == hash.end()) { 17 | number.push_back(val); 18 | hash[val] = number.size() - 1; 19 | return true; 20 | } 21 | 22 | return false; 23 | } 24 | 25 | /** Removes a value from the set. Returns true if the set contained the specified element. */ 26 | bool remove(int val) { 27 | if (hash.find(val) != hash.end()) { 28 | int loc = hash[val]; 29 | number[loc] = number[number.size() - 1]; 30 | number.pop_back(); 31 | 32 | hash[number[loc]] = loc; 33 | hash.erase(val); 34 | return true; 35 | } 36 | 37 | return false; 38 | } 39 | 40 | /** Get a random element from the set. */ 41 | int getRandom() { 42 | int r = rand() % number.size(); 43 | return number[r]; 44 | } 45 | }; 46 | 47 | /** 48 | * Your RandomizedSet object will be instantiated and called as such: 49 | * RandomizedSet* obj = new RandomizedSet(); 50 | * bool param_1 = obj->insert(val); 51 | * bool param_2 = obj->remove(val); 52 | * int param_3 = obj->getRandom(); 53 | */ 54 | -------------------------------------------------------------------------------- /chapter 14/637 二叉树的层平均值.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 1110. Delete Nodes And Return Forest 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | vector averageOfLevels(TreeNode* root) { 18 | queue que; 19 | vector average; 20 | 21 | if (root == NULL) { 22 | return average; 23 | } 24 | 25 | que.push(root); 26 | 27 | while (!que.empty()) { 28 | int tos = que.size(); 29 | double num = tos; 30 | double sum = 0; 31 | 32 | while (tos > 0) { 33 | tos--; 34 | TreeNode* tmp = que.front(); 35 | que.pop(); 36 | 37 | if (tmp->left != NULL) { 38 | que.push(tmp->left); 39 | } 40 | 41 | if (tmp->right != NULL) { 42 | que.push(tmp->right); 43 | } 44 | sum += tmp->val; 45 | } 46 | 47 | double averageVal = sum / num; 48 | average.push_back(averageVal); 49 | } 50 | 51 | return average; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /chapter 11/225 用队列实现栈.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 225. Implement Stack using Queues 3 | 4 | class MyStack { 5 | private: 6 | queue stk, tmp; 7 | 8 | public: 9 | /** Initialize your data structure here. */ 10 | MyStack() { 11 | 12 | } 13 | 14 | /** Push element x onto stack. */ 15 | void push(int x) { 16 | while (!stk.empty()) { 17 | tmp.push(stk.front()); 18 | stk.pop(); 19 | } 20 | 21 | stk.push(x); 22 | 23 | while (!tmp.empty()) { 24 | stk.push(tmp.front()); 25 | tmp.pop(); 26 | } 27 | 28 | return; 29 | 30 | } 31 | 32 | /** Removes the element on top of the stack and returns that element. */ 33 | int pop() { 34 | if (!stk.empty()) { 35 | int topVal = stk.front(); 36 | stk.pop(); 37 | return topVal; 38 | } 39 | 40 | // throw error 41 | return INT_MIN; 42 | } 43 | 44 | /** Get the top element. */ 45 | int top() { 46 | if (!stk.empty()) { 47 | return stk.front(); 48 | } 49 | 50 | // throw error 51 | return INT_MIN; 52 | } 53 | 54 | /** Returns whether the stack is empty. */ 55 | bool empty() { 56 | return stk.empty(); 57 | } 58 | }; 59 | 60 | /** 61 | * Your MyStack object will be instantiated and called as such: 62 | * MyStack* obj = new MyStack(); 63 | * obj->push(x); 64 | * int param_2 = obj->pop(); 65 | * int param_3 = obj->top(); 66 | * bool param_4 = obj->empty(); 67 | */ 68 | -------------------------------------------------------------------------------- /chapter 7/91 解码方法.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 91. Decode Ways 3 | 4 | class Solution { 5 | public: 6 | int toInt(string str, int i, int j) { 7 | // assert .... 8 | int number = 0; 9 | for (int k = i; k <= j; k++) { 10 | number = number * 10 + (str[k] - '0'); 11 | } 12 | 13 | return number; 14 | } 15 | 16 | int numDecodings(string s) { 17 | if (s.empty()) { 18 | return 0; 19 | } 20 | 21 | int len = s.size(); 22 | vector dp(len, 0); 23 | 24 | if ('0' < s[0] && s[0] <= '9') { 25 | dp[0] = 1; 26 | } else { 27 | dp[0] = 0; 28 | } 29 | 30 | if (dp[0] == 0 || len == 1) { 31 | return dp[0]; 32 | } 33 | 34 | int first = toInt(s, 1, 1); 35 | 36 | if (dp[0] > 0 && 0 < first && first <= 9) { 37 | dp[1] = dp[0]; 38 | } 39 | 40 | int second = toInt(s, 0, 1); 41 | if (10 <= second && second <= 26) { 42 | dp[1] += 1; 43 | } 44 | 45 | for (int i = 2; i < len; i++) { 46 | int tmp = toInt(s, i, i); 47 | if (0 < tmp && tmp <= 9 ) { 48 | dp[i] += dp[i - 1]; 49 | } 50 | 51 | tmp = toInt(s, i - 1, i); 52 | if (10 <= tmp && tmp <= 26) { 53 | dp[i] += dp[i - 2]; 54 | } 55 | } 56 | 57 | // for (int i = 1; i < len; i++) { 58 | // cout<next == nullptr) { 18 | return head; 19 | } 20 | 21 | ListNode* fast = head, *slow = head; 22 | while (fast->next != nullptr && (fast->next)->next != nullptr) { 23 | fast = (fast->next)->next; 24 | slow = slow->next; 25 | } 26 | 27 | ListNode* rhead = slow->next; 28 | slow->next = nullptr; 29 | head = sortList(head); 30 | rhead = sortList(rhead); 31 | 32 | ListNode* l1 = head, *l2 = rhead; 33 | ListNode* dummy = new ListNode(); 34 | ListNode* tail = dummy; 35 | while (l1 != nullptr && l2 != nullptr) { 36 | if (l1->val < l2->val) { 37 | tail->next = l1; 38 | l1 = l1->next; 39 | } else { 40 | tail->next = l2; 41 | l2 = l2->next; 42 | } 43 | tail = tail->next; 44 | } 45 | 46 | if (l1 != nullptr) { 47 | tail->next = l1; 48 | } else { 49 | tail->next = l2; 50 | } 51 | 52 | head = dummy->next; 53 | delete dummy; 54 | return head; 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /chapter 6/47 全排列2.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 47. Permutations II 3 | 4 | class Solution { 5 | public: 6 | void dfs(vector& nums, int depth, vector& path, vector& used, 7 | vector >& res) { 8 | 9 | int len = nums.size(); 10 | if (depth == len) { 11 | for (int i = 0; i < path.size(); i++) { 12 | cout< 0 && nums[depth] == nums[depth - 1] && !used[depth - 1])) { 20 | // return; 21 | // } 22 | 23 | for (int i = 0; i < len; i++) { 24 | if (used[i] || (i > 0 && nums[i] == nums[i - 1] && !used[i - 1])) { 25 | continue; 26 | } 27 | 28 | used[i] = true; 29 | path.push_back(nums[i]); 30 | 31 | dfs(nums, depth + 1, path, used, res); 32 | 33 | used[i] == false; 34 | path.pop_back(); 35 | } 36 | 37 | return; 38 | } 39 | 40 | vector> permuteUnique(vector& nums) { 41 | int len = nums.size(); 42 | vector > res; 43 | vector path; 44 | vector used(len, false); 45 | 46 | if (nums.empty()) { 47 | return res; 48 | } 49 | 50 | sort(nums.begin(), nums.end()); 51 | 52 | dfs(nums, 0, path, used, res); 53 | cout<<"res.size(): "<left == NULL && root->right == NULL) { 21 | if (parent->left == root) { 22 | return root->val; 23 | } else { 24 | return 0; 25 | } 26 | } 27 | 28 | int sum = 0; 29 | if (root->left != NULL) { 30 | sum += helper(root->left, root); 31 | } 32 | 33 | if (root->right != NULL) { 34 | sum += helper(root->right, root); 35 | } 36 | 37 | return sum; 38 | } 39 | 40 | int sumOfLeftLeaves(TreeNode* root) { 41 | int sum = 0; 42 | 43 | if (root == NULL) { 44 | return 0; 45 | } 46 | 47 | if (root->left == NULL && root->right == NULL) { 48 | return 0; 49 | } 50 | 51 | if (root->left != NULL) { 52 | sum += helper(root->left, root); 53 | } 54 | 55 | if (root->right != NULL) { 56 | sum += helper(root->right, root); 57 | } 58 | 59 | return sum; 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /chapter 8/312 戳气球.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 312. Burst Balloons 3 | 4 | // DP 5 | class Solution { 6 | public: 7 | int maxCoins(vector& nums) { 8 | if (nums.empty()) { 9 | return 0; 10 | } 11 | 12 | int len = nums.size(); 13 | if (len == 1) { 14 | return nums[0]; 15 | } 16 | 17 | vector > dp(len, vector(len, 0)); 18 | dp[0][0] = nums[0] * nums[1]; 19 | dp[len - 1][len - 1] = nums[len - 1] * nums[len - 2]; 20 | for (int i = 1; i < len - 1; i++) { 21 | dp[i][i] = nums[i - 1] * nums[i] * nums[i + 1]; 22 | } 23 | 24 | for (int l = 1; l < len; l++) { 25 | for (int i = 0; i < len - l; i++) { 26 | for (int k = i; k <= i + l; k++) { 27 | int curr = nums[k]; 28 | int currdp = 0; 29 | 30 | if (i - 1 >= 0) { 31 | curr *= nums[i - 1]; 32 | } 33 | 34 | if (i + l + 1 <= len - 1) { 35 | curr *= nums[i + l + 1]; 36 | } 37 | 38 | if (k - 1 >= i) { 39 | currdp += dp[i][k - 1]; 40 | } 41 | 42 | if (k + 1 <= i + l) { 43 | currdp += dp[k + 1][i + l]; 44 | } 45 | 46 | dp[i][i + l] = max(dp[i][i + l], curr + currdp); 47 | } 48 | } 49 | } 50 | 51 | return dp[0][len - 1]; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /chapter 7/542 01矩阵.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 542. 01 Matrix 3 | 4 | class Solution { 5 | public: 6 | const int MAX = 10001; 7 | 8 | vector> updateMatrix(vector>& matrix) { 9 | 10 | if (matrix.empty()) { 11 | vector > tmp; 12 | return tmp; 13 | } 14 | 15 | int row = matrix.size(); 16 | int col = matrix[0].size(); 17 | vector > dis(row, vector (col, MAX)); 18 | 19 | for (int i = 0; i < row; i++) { 20 | for (int j = 0; j < col; j++) { 21 | if (matrix[i][j] == 0) { 22 | dis[i][j] = 0; 23 | continue; 24 | } 25 | 26 | if (i > 0) { 27 | dis[i][j] = min(dis[i][j], dis[i - 1][j] + 1); 28 | } 29 | 30 | if (j > 0) { 31 | dis[i][j] = min(dis[i][j], dis[i][j - 1] + 1); 32 | } 33 | } 34 | } 35 | 36 | for (int i = row - 1; i >= 0; i--) { 37 | for (int j = col - 1; j >= 0; j--) { 38 | if (matrix[i][j] == 0) { 39 | dis[i][j] = 0; 40 | continue; 41 | } 42 | 43 | if (i < row - 1) { 44 | dis[i][j] = min(dis[i][j], dis[i + 1][j] + 1); 45 | } 46 | 47 | if (j < col - 1) { 48 | dis[i][j] = min(dis[i][j], dis[i][j + 1] + 1); 49 | } 50 | } 51 | } 52 | 53 | return dis; 54 | 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /chapter 14/106 从中序与后序遍历序列构造二叉树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 106. Construct Binary Tree from Inorder and Postorder Traversal 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | TreeNode* buildTree(vector& inorder, vector& postorder) { 18 | 19 | if (inorder.empty() || postorder.empty()) { 20 | return NULL; 21 | } 22 | 23 | // assert valid input... 24 | int inLen = inorder.size(); 25 | int postLen = postorder.size(); 26 | TreeNode* ptr = new TreeNode(postorder[postLen - 1]); 27 | 28 | if (inLen == 1) { 29 | return ptr; 30 | } 31 | 32 | int curr = 0; 33 | for (curr = 0; curr < inLen; curr++) { 34 | if (inorder[curr] == ptr->val) { 35 | break; 36 | } 37 | } 38 | 39 | vector leftIn(inorder.begin(), inorder.begin() + curr); 40 | vector rightIn(inorder.begin() + curr + 1, inorder.end()); 41 | vector leftPost(postorder.begin(), postorder.begin() + leftIn.size()); 42 | vector rightPost(postorder.begin() + leftIn.size(), postorder.end() - 1); 43 | 44 | ptr->left = buildTree(leftIn, leftPost); 45 | ptr->right = buildTree(rightIn, rightPost); 46 | 47 | return ptr; 48 | } 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /chapter 9/67 二进制求和.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 67. Add Binary 3 | 4 | class Solution { 5 | public: 6 | string addBinary(string a, string b) { 7 | if (a.empty()) { 8 | return b; 9 | } else if (b.empty()) { 10 | return a; 11 | } 12 | 13 | int aptr = a.size() - 1; 14 | int bptr = b.size() - 1; 15 | int add = 0; 16 | string sumStr = ""; 17 | 18 | while (aptr >= 0 && bptr >= 0) { 19 | int sum = (a[aptr] - '0') + (b[bptr] - '0') + add; 20 | int curr = sum % 2; 21 | sumStr = char(curr + '0') + sumStr; 22 | 23 | add = sum / 2; 24 | aptr--; 25 | bptr--; 26 | } 27 | 28 | while (aptr >= 0 && add > 0) { 29 | int sum = (a[aptr] - '0') + add; 30 | int curr = sum % 2; 31 | sumStr = char(curr + '0') + sumStr; 32 | 33 | add = sum / 2; 34 | aptr --; 35 | } 36 | 37 | if (aptr >= 0) { 38 | sumStr = a.substr(0, aptr + 1) + sumStr; 39 | aptr = -1; 40 | } 41 | 42 | 43 | while (bptr >= 0 && add > 0) { 44 | int sum = (b[bptr] - '0') + add; 45 | int curr = sum % 2; 46 | sumStr = char(curr + '0') + sumStr; 47 | 48 | add = sum / 2; 49 | bptr --; 50 | } 51 | 52 | if (bptr >= 0) { 53 | sumStr = b.substr(0, bptr + 1) + sumStr; 54 | bptr = -1; 55 | } 56 | 57 | if (add > 0) { 58 | sumStr = char(add + '0') + sumStr; 59 | } 60 | return sumStr; 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /chapter 6/695 岛屿的最大面积.cpp: -------------------------------------------------------------------------------- 1 | // 695.Max Area of Island 2 | 3 | class Solution { 4 | public: 5 | int maxAreaOfIsland(vector>& grid) { 6 | if (grid.empty()) { 7 | return 0; 8 | } 9 | 10 | int maxArea = 0; 11 | int row = grid.size(); 12 | int col = grid[0].size(); 13 | vector direction{-1, 0, 1, 0, -1}; 14 | 15 | for (int i = 0; i < row; i++) { 16 | for (int j = 0; j < col; j++) { 17 | if (grid[i][j] == 0) { 18 | continue; 19 | } 20 | 21 | int area = 1; 22 | grid[i][j] = 0; 23 | stack > island; 24 | island.push(pair (i, j)); 25 | while (!island.empty()) { 26 | pair tmp = island.top(); 27 | island.pop(); 28 | 29 | int xLoc = tmp.first; 30 | int yLoc = tmp.second; 31 | for (int k = 0; k <= direction.size() - 2; k++) { 32 | int x = xLoc + direction[k]; 33 | int y = yLoc + direction[k + 1]; 34 | if (0 <= x && x < row && 0 <= y && y < col && grid[x][y] == 1) { 35 | area++; 36 | grid[x][y] = 0; 37 | island.push(pair (x, y)); 38 | } 39 | } 40 | 41 | } 42 | 43 | maxArea = max(maxArea, area); 44 | 45 | } 46 | } 47 | 48 | return maxArea; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /chapter 11/232 用栈实现队列.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 232. Implement Queue using Stacks 3 | 4 | class MyQueue { 5 | stack que, tmp; 6 | int front; 7 | public: 8 | /** Initialize your data structure here. */ 9 | MyQueue() { 10 | 11 | } 12 | 13 | /** Push element x to the back of queue. */ 14 | void push(int x) { 15 | if (que.empty()) { 16 | front = x; 17 | } 18 | 19 | que.push(x); 20 | return; 21 | } 22 | 23 | /** Removes the element from in front of queue and returns that element. */ 24 | int pop() { 25 | if (que.empty()) { 26 | return INT_MIN; 27 | } 28 | 29 | transfer(que, tmp); 30 | int ret = tmp.top(); 31 | tmp.pop(); 32 | 33 | if (!tmp.empty()) { 34 | front = tmp.top(); 35 | } 36 | 37 | transfer(tmp,que); 38 | return ret; 39 | } 40 | 41 | /** Get the front element. */ 42 | int peek() { 43 | if (!que.empty()) { 44 | return front; 45 | } 46 | 47 | // throw error 48 | return que.top(); 49 | } 50 | 51 | /** Returns whether the queue is empty. */ 52 | bool empty() { 53 | return que.empty(); 54 | } 55 | 56 | void transfer(stack& orc, stack& des) { 57 | // assert(des.empty()); 58 | while (!orc.empty()) { 59 | int tmp = orc.top(); 60 | orc.pop(); 61 | des.push(tmp); 62 | } 63 | 64 | return; 65 | } 66 | }; 67 | 68 | /** 69 | * Your MyQueue object will be instantiated and called as such: 70 | * MyQueue* obj = new MyQueue(); 71 | * obj->push(x); 72 | * int param_2 = obj->pop(); 73 | * int param_3 = obj->peek(); 74 | * bool param_4 = obj->empty(); 75 | */ 76 | -------------------------------------------------------------------------------- /chapter 6/257 二叉树的所有路径.cpp: -------------------------------------------------------------------------------- 1 | // 257. Binary Tree Paths 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | void dfs(TreeNode* curr, vector& path, vector >& res) { 17 | if (curr == nullptr) { 18 | return; 19 | } 20 | 21 | path.push_back(curr->val); 22 | if (curr->left == nullptr && curr->right == nullptr) { 23 | res.push_back(path); 24 | } else { 25 | dfs(curr->left, path, res); 26 | dfs(curr->right, path, res); 27 | } 28 | path.pop_back(); 29 | 30 | return; 31 | } 32 | 33 | vector binaryTreePaths(TreeNode* root) { 34 | vector pathStr; 35 | vector path; 36 | vector > res; 37 | 38 | if (root == nullptr) { 39 | return pathStr; 40 | } 41 | 42 | dfs(root, path, res); 43 | for (int i = 0; i < res.size(); i++) { 44 | int len = res[i].size(); 45 | string str = ""; 46 | 47 | for (int j = 0; j < len; j++) { 48 | if (!str.empty()) { 49 | str += ("->" + to_string(res[i][j])); 50 | } else { 51 | str = to_string(res[i][j]); 52 | } 53 | } 54 | 55 | pathStr.push_back(str); 56 | } 57 | 58 | return pathStr; 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /chapter 11/870 优势洗牌.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 870. Advantage Shuffle 3 | 4 | class Solution { 5 | public: 6 | struct cmp { 7 | bool operator ()(pair node1, pair node2) { 8 | return node1.first > node2.first; 9 | } 10 | }; 11 | 12 | vector advantageCount(vector& A, vector& B) { 13 | 14 | int len = A.size(); 15 | vector ret; 16 | queue unmatch; 17 | priority_queue, vector >, cmp> aheap, bheap; 18 | 19 | if (A.empty() || B.empty() || A.size() != B.size()) { 20 | return ret; 21 | } 22 | 23 | for (int i = 0; i < len; i++) { 24 | aheap.push({A[i], i}); 25 | bheap.push({B[i], i}); 26 | } 27 | 28 | ret.resize(len, -1); 29 | while (!aheap.empty() && !bheap.empty()) { 30 | pair minb = bheap.top(); 31 | bheap.pop(); 32 | 33 | while (!aheap.empty() && (aheap.top()).first <= minb.first) { // note: ' <= ', not ' < ' 34 | pair tmp = aheap.top(); 35 | unmatch.push(tmp.first); 36 | aheap.pop(); 37 | } 38 | 39 | if (!aheap.empty()) { 40 | pair mina = aheap.top(); 41 | aheap.pop(); 42 | 43 | ret[minb.second] = mina.first; 44 | 45 | } 46 | } 47 | 48 | for (int i = 0; i < len; i++) { 49 | if (ret[i] == -1) { 50 | // assert(!unmatch.empty()); 51 | int tmp = unmatch.front(); 52 | unmatch.pop(); 53 | ret[i] = tmp; 54 | } 55 | } 56 | 57 | return ret; 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /chapter 7/10 正则表达式匹配.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 10. Regular Expression Matching 3 | 4 | class Solution { 5 | public: 6 | bool isMatch(string s, string p) { 7 | int sLen = s.size(); 8 | int pLen = p.size(); 9 | 10 | vector > dp(sLen + 1, vector (pLen + 1, false)); 11 | dp[0][0] = true; 12 | 13 | for (int j = 1; j <= pLen; j++) { 14 | if (p[j - 1] == '*') { 15 | if (j - 2 < 0) { 16 | dp[0][j] = false; 17 | } else { 18 | dp[0][j] = dp[0][j - 2] 19 | } 20 | 21 | } else { 22 | dp[0][j] = false; 23 | } 24 | } 25 | 26 | for (int i = 1; i <= sLen; i++) { 27 | dp[i][0] = false; 28 | } 29 | 30 | 31 | for (int i = 1; i <= sLen; i++) { 32 | for (int j = 1; j <= pLen; j++) { 33 | 34 | if (p[j - 1] == '.') { 35 | dp[i][j] = dp[i - 1][j - 1]; 36 | continue; 37 | } 38 | 39 | if (p[j - 1] == '*') { 40 | if (j - 2 < 0) { 41 | dp[i][j] = false; 42 | continue; 43 | } 44 | 45 | dp[i][j] = dp[i][j - 2]; 46 | 47 | if (p[j - 2] == s[i - 1]) { 48 | dp[i][j] = dp[i][j] || dp[i - 1][j - 2] || dp[i - 1][j]; 49 | } 50 | 51 | } else { 52 | if (s[i - 1] == p[j - 1]) { 53 | dp[i][j] = dp[i - 1][j - 1]; 54 | } else { 55 | dp[i][j] = false; 56 | } 57 | } 58 | } 59 | } 60 | 61 | return dp[sLen][pLen]; 62 | 63 | } 64 | }; 65 | -------------------------------------------------------------------------------- /chapter 6/417 太平洋大西洋水流问题.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 417. Pacific Atlantic Water Flow 3 | 4 | class Solution { 5 | public: 6 | void dfs(vector>& heights, vector>& reach, int i, int j) { 7 | // assert(...); 8 | int row = heights.size(); 9 | int col = heights[0].size(); 10 | 11 | if (reach[i][j] == 1) { 12 | return; 13 | } 14 | 15 | reach[i][j] = 1; 16 | vector direction {-1, 0, 1, 0, -1}; 17 | for (int k = 0; k < direction.size() - 1; k++) { 18 | int x = i + direction[k]; 19 | int y = j + direction[k + 1]; 20 | if (0 <= x && x < row && 0 <= y && y < col 21 | && heights[x][y] >= heights[i][j]) { 22 | dfs(heights, reach, x, y); 23 | } 24 | } 25 | 26 | return; 27 | } 28 | 29 | vector> pacificAtlantic(vector>& heights) { 30 | vector > res; 31 | 32 | if (heights.empty()) { 33 | return res; 34 | } 35 | 36 | int row = heights.size(); 37 | int col = heights[0].size(); 38 | vector > reachPac(row, vector (col, 0)); 39 | vector > reachAtl(row, vector (col, 0)); 40 | 41 | for (int i = 0; i < row; i++) { 42 | dfs(heights, reachPac, i, 0); 43 | dfs(heights, reachAtl, i, col - 1); 44 | } 45 | 46 | for (int j = 0; j < col; j++) { 47 | dfs(heights, reachPac, 0, j); 48 | dfs(heights, reachAtl, row - 1, j); 49 | } 50 | 51 | for (int i = 0; i < row; i++) { 52 | for (int j = 0; j < col; j++) { 53 | if (reachPac[i][j] == 1 && reachAtl[i][j] == 1) { 54 | vector tmp {i, j}; 55 | res.push_back(tmp); 56 | } 57 | } 58 | } 59 | 60 | return res; 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /chapter 6/79 单词搜索.cpp: -------------------------------------------------------------------------------- 1 | // 79. Word Search 2 | 3 | class Solution { 4 | public: 5 | bool dfs(vector >& board, int i, int j, int depth, 6 | string word, vector >& used) { 7 | 8 | // assert(board[i][j] == word[depth]); 9 | if (board[i][j] != word[depth]) { 10 | return false; // cann't happen. 11 | } 12 | 13 | // assert(!board.empty() && !used.empty()) and .... 14 | if (depth == word.size() - 1) { 15 | return true; 16 | } 17 | 18 | 19 | used[i][j] = true; 20 | 21 | int row = board.size(); 22 | int col = board[0].size(); 23 | vector direction {-1, 0, 1, 0, -1}; 24 | for (int k = 0; k < direction.size() - 1; k++) { 25 | int x = i + direction[k]; 26 | int y = j + direction[k + 1]; 27 | if (0 <= x && x < row && 0 <= y && y < col 28 | && board[x][y] == word[depth + 1] && used[x][y] == false) { 29 | 30 | if (dfs(board, x, y, depth + 1, word, used)) { 31 | used[i][j] = false; 32 | return true; 33 | } 34 | } 35 | } 36 | 37 | used[i][j] = false; 38 | return false; 39 | } 40 | 41 | 42 | bool exist(vector>& board, string word) { 43 | if (board.empty()) { 44 | return false; 45 | } 46 | 47 | int row = board.size(); 48 | int col = board[0].size(); 49 | vector > used(row, vector (col, false)); 50 | 51 | for (int i = 0; i < row; i++) { 52 | for (int j = 0; j < col; j++) { 53 | if (board[i][j] != word[0]) { 54 | continue; 55 | } 56 | 57 | if (dfs(board, i, j, 0, word, used)) { 58 | return true; 59 | } 60 | } 61 | } 62 | 63 | return false; 64 | 65 | } 66 | }; 67 | -------------------------------------------------------------------------------- /chapter 14/109 将有序链表转化为二叉搜索树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 109. Convert Sorted List to Binary Search Tree 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode() : val(0), next(nullptr) {} 10 | * ListNode(int x) : val(x), next(nullptr) {} 11 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 12 | * }; 13 | */ 14 | /** 15 | * Definition for a binary tree node. 16 | * struct TreeNode { 17 | * int val; 18 | * TreeNode *left; 19 | * TreeNode *right; 20 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 21 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 22 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 23 | * }; 24 | */ 25 | class Solution { 26 | public: 27 | int getLen(ListNode* head) { 28 | ListNode* ptr = head; 29 | int len = 0; 30 | 31 | while (ptr != NULL) { 32 | len ++; 33 | ptr = ptr->next; 34 | } 35 | 36 | return len; 37 | } 38 | 39 | void inorderAndAssignment(TreeNode* root, ListNode*& curr) { 40 | if (root == NULL || curr == NULL) { 41 | return; 42 | } 43 | 44 | inorderAndAssignment(root->left, curr); 45 | root->val = curr->val; 46 | curr = curr->next; 47 | inorderAndAssignment(root->right, curr); 48 | return; 49 | } 50 | 51 | 52 | TreeNode* buildTree(int len) { 53 | if (len <= 0) { 54 | return NULL; 55 | } 56 | 57 | TreeNode* ptr = new TreeNode(); 58 | if (len == 1) { 59 | return ptr; 60 | } 61 | 62 | int mid = len / 2; 63 | ptr->left = buildTree(mid); 64 | ptr->right = buildTree(len - mid - 1); 65 | 66 | return ptr; 67 | } 68 | 69 | TreeNode* sortedListToBST(ListNode* head) { 70 | if (head == NULL) { 71 | return NULL; 72 | } 73 | 74 | int len = getLen(head); 75 | TreeNode* root = buildTree(len); 76 | inorderAndAssignment(root, head); 77 | 78 | return root; 79 | } 80 | }; 81 | -------------------------------------------------------------------------------- /chapter 6/51 N皇后.cpp: -------------------------------------------------------------------------------- 1 | // 51. N-Queens 2 | 3 | class Solution { 4 | public: 5 | void dfs(vector& curr, int i, int n, 6 | vector& colUsed, vector& leftDiag, vector& rightDiag, 7 | vector >& res) { 8 | 9 | for (int j = 0; j < n; j++) { 10 | if (colUsed[j] || leftDiag[i - j + n - 1] || rightDiag[i + j]) { 11 | continue; 12 | } 13 | 14 | colUsed[j] = true; 15 | leftDiag[i - j + n - 1]= true; 16 | rightDiag[i + j]= true; 17 | curr.push_back(j); 18 | 19 | if (i == n - 1) { 20 | res.push_back(curr); 21 | } else { 22 | dfs(curr, i + 1, n, colUsed, leftDiag, rightDiag, res); 23 | } 24 | 25 | leftDiag[i - j + n - 1]= false; 26 | rightDiag[i + j] = false; 27 | colUsed[j] = false; 28 | curr.pop_back(); 29 | } 30 | 31 | return; 32 | } 33 | 34 | vector transferToStr(vector location) { 35 | vector res; 36 | int len = location.size(); 37 | for (int i = 0; i < len; i++) { 38 | int loc = location[i]; 39 | string tmp = ""; 40 | for (int j = 0; j < len; j++) { 41 | if (j == loc) { 42 | tmp += "Q"; 43 | } else { 44 | tmp += "."; 45 | } 46 | } 47 | res.push_back(tmp); 48 | } 49 | 50 | return res; 51 | } 52 | 53 | vector> solveNQueens(int n) { 54 | vector curr; 55 | vector > res; 56 | 57 | vector colUsed(n, false); 58 | vector leftDiag(2 * n - 1, false); 59 | vector rightDiag(2 * n - 1, false); 60 | 61 | dfs(curr, 0, n, colUsed, leftDiag, rightDiag, res); 62 | 63 | vector > queens; 64 | for (int i = 0; i < res.size(); i++) { 65 | vector tmp = transferToStr(res[i]); 66 | queens.push_back(tmp); 67 | } 68 | 69 | return queens; 70 | } 71 | }; 72 | -------------------------------------------------------------------------------- /chapter 6/130 被环绕的区域.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 130. Surrounded Regions 3 | 4 | class Solution { 5 | public: 6 | void dfs(vector>& board, int i, int j, 7 | vector >& visited) { 8 | // assert... 9 | 10 | int row = board.size(); 11 | int col = board[0].size(); 12 | vector direction {-1, 0, 1, 0, -1}; 13 | if (i < 0 || i >= row || j < 0 || j >= col || board[i][j] != 'O' 14 | || visited[i][j]) { 15 | 16 | return; 17 | } 18 | 19 | visited[i][j] = true; 20 | for (int k = 0; k < direction.size() - 1; k++) { 21 | int x = i + direction[k]; 22 | int y = j + direction[k + 1]; 23 | if (0 <= x && x < row && 0 <= y && y < col 24 | && board[x][y] == 'O' && !visited[x][y]) { 25 | 26 | dfs(board, x, y, visited); 27 | } 28 | } 29 | 30 | return; 31 | } 32 | 33 | void solve(vector>& board) { 34 | if (board.empty()) { 35 | return; 36 | } 37 | 38 | int row = board.size(); 39 | int col = board[0].size(); 40 | vector > visited(row, vector (col, false)); 41 | 42 | for (int i = 0; i < row; i++) { 43 | if (board[i][0] == 'O' && !visited[i][0]) { 44 | dfs(board, i, 0, visited); 45 | } 46 | 47 | if (board[i][col - 1] == 'O' && !visited[i][col - 1]) { 48 | dfs(board, i, col - 1, visited); 49 | } 50 | } 51 | 52 | for (int j = 0; j < col; j++) { 53 | if (board[0][j] == 'O' && !visited[0][j]) { 54 | dfs(board, 0, j, visited); 55 | } 56 | 57 | if (board[row - 1][j] == 'O' && !visited[row - 1][j]) { 58 | dfs(board, row - 1, j, visited); 59 | } 60 | } 61 | 62 | for (int i = 0; i < row; i++) { 63 | for (int j = 0; j < col; j++) { 64 | if (board[i][j] == 'O' && !visited[i][j]) { 65 | board[i][j] = 'X'; 66 | visited[i][j] = true; 67 | } 68 | } 69 | } 70 | 71 | return; 72 | } 73 | }; 74 | -------------------------------------------------------------------------------- /chapter 6/934 最短的桥.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 934. Shortest Bridge 3 | 4 | class Solution { 5 | public: 6 | void dfs(vector >& A, int i, int j, queue >& points) { 7 | // assert.... 8 | int row = A.size(); 9 | int col = A[0].size(); 10 | 11 | if (i < 0 || i >= row || j < 0 || j >= col || A[i][j] != 1) { 12 | return; 13 | } 14 | 15 | A[i][j] = 2; 16 | points.push(pair (i, j)); 17 | vector direction {-1, 0, 1, 0, -1}; 18 | for (int k = 0; k < direction.size() - 1; k++) { 19 | int x = i + direction[k]; 20 | int y = j + direction[k + 1]; 21 | if (0 <= x && x < row && 0 <= y && y < col && A[x][y] == 1) { 22 | dfs(A, x, y, points); 23 | } 24 | } 25 | 26 | return; 27 | } 28 | 29 | int shortestBridge(vector>& A) { 30 | if (A.empty()) { 31 | return -1; 32 | } 33 | 34 | int row = A.size(); 35 | int col = A[0].size(); 36 | bool flipped = false; 37 | queue > points; 38 | 39 | for (int i = 0; i < row; i++) { 40 | if (flipped) { 41 | break; 42 | } 43 | for (int j = 0; j < col; j++) { 44 | if (A[i][j] == 1) { 45 | dfs(A, i, j, points); 46 | flipped = true; 47 | break; 48 | } 49 | } 50 | } 51 | 52 | 53 | int level = 0; 54 | vector direction {-1, 0, 1, 0, -1}; 55 | while (!points.empty()) { 56 | int numPoints = points.size(); 57 | level ++; 58 | 59 | while (numPoints > 0) { 60 | pair tmp = points.front(); 61 | points.pop(); 62 | 63 | int xLoc = tmp.first; 64 | int yLoc = tmp.second; 65 | 66 | for (int k = 0; k < direction.size() - 1; k++) { 67 | int x = xLoc + direction[k]; 68 | int y = yLoc + direction[k + 1]; 69 | 70 | if (0 <= x && x < row && 0 <= y && y < col) { 71 | 72 | if (A[x][y] == 2) { 73 | continue; 74 | } 75 | 76 | if (A[x][y] == 1) { 77 | return level - 1; 78 | } 79 | 80 | if (A[x][y] == 0) { 81 | A[x][y] = 2; 82 | points.push({x, y}); 83 | } 84 | } 85 | } 86 | 87 | numPoints --; 88 | } 89 | } 90 | 91 | return 0; 92 | 93 | } 94 | }; 95 | -------------------------------------------------------------------------------- /chapter 8/241 为运算表达式设置优先级.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 241. Different Ways to Add Parentheses 3 | 4 | // Use DP 5 | 6 | class Solution { 7 | public: 8 | int compute(int x, int y, char opt) { 9 | switch (opt) { 10 | case '*' : 11 | return x * y; 12 | break; 13 | case '+': 14 | return x + y; 15 | break; 16 | case '-' : 17 | return x - y; 18 | break; 19 | default: 20 | // throw error 21 | return INT_MIN; 22 | } 23 | } 24 | 25 | vector computeDp(int x, int y, vector > dpVal, char opt) { 26 | 27 | int lenx = dpVal[x].size(); 28 | int leny = dpVal[y].size(); 29 | vector resVec; 30 | 31 | // assert(0 <= x && x <= lenx); 32 | // assert(0 <= y && y <= leny); 33 | for (int i = 0; i < lenx; i++) { 34 | for (int j = 0; j < leny; j++) { 35 | 36 | int tmp = compute(dpVal[x][i], dpVal[y][j], opt); 37 | resVec.push_back(tmp); 38 | } 39 | } 40 | 41 | return resVec; 42 | } 43 | 44 | vector diffWaysToCompute(string expression) { 45 | // assert expression is valid... 46 | 47 | int len = expression.size(); 48 | vector ret; 49 | 50 | if (expression.empty()) { 51 | return ret; 52 | } 53 | 54 | vector number; 55 | vector opt; 56 | 57 | int k = 0; 58 | while (k < len) { 59 | string tmp = ""; 60 | int j = k; 61 | while (j < len && '0' <= expression[j] && expression[j] <= '9') { 62 | tmp += expression[j]; 63 | j++; 64 | } 65 | 66 | number.push_back(stoi(tmp)); 67 | if (j < len) { 68 | opt.push_back(expression[j]); 69 | } 70 | 71 | k = j + 1; 72 | } 73 | 74 | int numLen = number.size(); 75 | int optLen = opt.size(); 76 | vector > dp(numLen, vector(numLen, -1)); 77 | vector > dpVal; 78 | 79 | for (int i = 0; i < numLen; i++) { 80 | vector tmp {number[i]}; 81 | dpVal.push_back(tmp); 82 | dp[i][i] = dpVal.size() - 1; 83 | } 84 | 85 | for (int l = 1; l < numLen; l++) { 86 | for (int i = 0; i < numLen - l; i++) { 87 | vector resVec; 88 | 89 | for (int j = i; j < i + l; j++) { 90 | vector tmp = computeDp(dp[i][j], dp[j + 1][i + l], dpVal, opt[j]); 91 | resVec.insert(resVec.end(), tmp.begin(), tmp.end()); 92 | } 93 | 94 | dpVal.push_back(resVec); 95 | dp[i][i + l] = dpVal.size() - 1; 96 | } 97 | } 98 | 99 | int loc = dp[0][numLen - 1]; 100 | return dpVal[loc]; 101 | 102 | } 103 | }; 104 | -------------------------------------------------------------------------------- /chapter 14/450 删除二叉搜索树中的节点.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 450. Delete Node in a BST 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | class Solution { 16 | public: 17 | TreeNode* search(TreeNode* root, int key, TreeNode*& parent) { 18 | TreeNode* ptr = root; 19 | 20 | while (ptr != NULL) { 21 | if (ptr->val == key) { 22 | break; 23 | } else if (ptr->val < key) { 24 | parent = ptr; 25 | ptr = ptr->right; 26 | } else { 27 | parent = ptr; 28 | ptr = ptr->left; 29 | } 30 | } 31 | 32 | return ptr; 33 | } 34 | 35 | TreeNode* deleteNode(TreeNode* root, TreeNode* delNode, TreeNode* parent) { 36 | if (root == NULL || delNode == NULL) { 37 | return root; 38 | } 39 | 40 | if (delNode->left == NULL && delNode->right == NULL) { 41 | delete delNode; 42 | if (parent != NULL) { 43 | // assert(delNode != root); 44 | if (parent->left == delNode) { 45 | parent->left = NULL; 46 | } else { 47 | parent->right = NULL; 48 | } 49 | 50 | return root; 51 | } 52 | return NULL; 53 | } 54 | 55 | TreeNode* ptr = NULL; 56 | TreeNode* pred = delNode; 57 | if (delNode->left != NULL) { 58 | ptr = delNode->left; 59 | while (ptr->right != NULL) { 60 | pred = ptr; 61 | ptr = ptr->right; 62 | } 63 | } else { 64 | // assert(delNode->right != NULL); 65 | ptr = delNode->right; 66 | while (ptr->left != NULL) { 67 | pred = ptr; 68 | ptr = ptr->left; 69 | } 70 | } 71 | 72 | delNode->val = ptr->val; 73 | root = deleteNode(root, ptr, pred); 74 | 75 | return root; 76 | } 77 | 78 | TreeNode* deleteNode(TreeNode* root, int key) { 79 | if (root == NULL) { 80 | return NULL; 81 | } 82 | 83 | if (root->left == NULL && root->right == NULL) { 84 | if (root->val == key) { 85 | delete root; 86 | return NULL; 87 | } else { 88 | return root; 89 | } 90 | } 91 | 92 | TreeNode* parent = NULL; 93 | TreeNode* delNode = search(root, key, parent); 94 | 95 | while (delNode != NULL) { 96 | root = deleteNode(root, delNode, parent); 97 | 98 | parent = NULL; 99 | delNode = search(root, key, parent); 100 | } 101 | 102 | return root; 103 | } 104 | }; 105 | -------------------------------------------------------------------------------- /chapter 14/208 实现前缀树(Trie).cpp: -------------------------------------------------------------------------------- 1 | 2 | // 208. Implement Trie (Prefix Tree) 3 | 4 | struct Node { 5 | char ch; 6 | vector children; 7 | bool isEnd; 8 | 9 | Node() { 10 | ch = '\0'; 11 | isEnd = false; 12 | children.resize(26, NULL); 13 | } 14 | 15 | Node(char c) { 16 | ch = c; 17 | isEnd = false; 18 | children.resize(26, NULL); 19 | } 20 | }; 21 | 22 | 23 | class Trie { 24 | private: 25 | Node* root; 26 | 27 | public: 28 | /** Initialize your data structure here. */ 29 | Trie() { 30 | root = new Node(); 31 | } 32 | 33 | /** Inserts a word into the trie. */ 34 | void insert(string word) { 35 | int len = word.size(); 36 | Node* ptr = root; 37 | 38 | for (int i = 0; i < len; i++) { 39 | int loc = word[i] - 'a'; 40 | if ((ptr->children)[loc] == NULL) { 41 | Node* tmp = new Node(word[i]); 42 | (ptr->children)[loc] = tmp; 43 | } 44 | 45 | ptr = (ptr->children[loc]); 46 | if (i == len - 1) { 47 | ptr->isEnd = true; 48 | } 49 | 50 | } 51 | 52 | return; 53 | } 54 | 55 | /** Returns if the word is in the trie. */ 56 | bool search(string word) { 57 | if (word.empty()) { 58 | return false; 59 | } 60 | 61 | int loc = word[0] - 'a'; 62 | int len = word.size(); 63 | Node* ptr = (root->children)[loc]; 64 | 65 | for (int i = 0; i < len; i++) { 66 | if (ptr == NULL || ptr->ch != word[i]) { 67 | return false; 68 | } 69 | 70 | if (i == len - 1) { 71 | if (ptr->isEnd) { 72 | return true; 73 | } else { 74 | return false; 75 | } 76 | } 77 | 78 | int nextLoc = word[i + 1] - 'a'; 79 | ptr = (ptr->children)[nextLoc]; 80 | } 81 | 82 | // not happen 83 | return false; 84 | 85 | } 86 | 87 | /** Returns if there is any word in the trie that starts with the given prefix. */ 88 | bool startsWith(string prefix) { 89 | if (prefix.empty()) { 90 | return false; 91 | } 92 | 93 | int loc = prefix[0] - 'a'; 94 | int len = prefix.size(); 95 | Node* ptr = (root->children)[loc]; 96 | 97 | for (int i = 0; i < len; i++) { 98 | if (ptr == NULL || ptr->ch != prefix[i]) { 99 | return false; 100 | } 101 | 102 | if (i == len - 1) { 103 | return true; 104 | } 105 | 106 | int nextLoc = prefix[i + 1] - 'a'; 107 | ptr = (ptr->children)[nextLoc]; 108 | } 109 | 110 | // not happen 111 | return false; 112 | 113 | } 114 | }; 115 | 116 | /** 117 | * Your Trie object will be instantiated and called as such: 118 | * Trie* obj = new Trie(); 119 | * obj->insert(word); 120 | * bool param_2 = obj->search(word); 121 | * bool param_3 = obj->startsWith(prefix); 122 | */ 123 | -------------------------------------------------------------------------------- /chapter 14/99 恢复二叉搜索树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 99. Recover Binary Search Tree 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 13 | * }; 14 | */ 15 | 16 | 17 | // space: O(log n) 18 | 19 | class Solution { 20 | public: 21 | 22 | void recoverTree(TreeNode* root) { 23 | stack stk; 24 | TreeNode* ptr = root; 25 | TreeNode* pred = NULL; 26 | TreeNode* first = NULL; 27 | TreeNode* second = NULL; 28 | 29 | if (root == NULL) { 30 | return; 31 | } 32 | 33 | while (ptr != NULL || !stk.empty()) { 34 | while (ptr != NULL) { 35 | stk.push(ptr); 36 | ptr = ptr->left; 37 | } 38 | 39 | if (!stk.empty()) { 40 | ptr = stk.top(); 41 | stk.pop(); 42 | 43 | if (pred != NULL) { 44 | if (pred->val > ptr->val) { 45 | if (first == NULL) { 46 | first = pred; 47 | second = ptr; 48 | } else { 49 | second = ptr; 50 | } 51 | } 52 | } 53 | 54 | pred = ptr; 55 | ptr = ptr->right; 56 | } 57 | } 58 | 59 | if (first != NULL && second != NULL) { 60 | int tmp = first->val; 61 | first->val = second->val; 62 | second->val = tmp; 63 | } 64 | 65 | return; 66 | 67 | } 68 | }; 69 | 70 | 71 | 72 | 73 | // 99. Recover Binary Search Tree 74 | 75 | /** 76 | * Definition for a binary tree node. 77 | * struct TreeNode { 78 | * int val; 79 | * TreeNode *left; 80 | * TreeNode *right; 81 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 82 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 83 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 84 | * }; 85 | */ 86 | 87 | 88 | 89 | // space : O(n); 90 | //class Solution { 91 | //public: 92 | // void inorder(TreeNode* root, vector& ret) { 93 | // 94 | // if (root == NULL) { 95 | // return; 96 | // } 97 | // 98 | // inorder(root->left, ret); 99 | // ret.push_back(root); 100 | // inorder(root->right, ret); 101 | // 102 | // return; 103 | // } 104 | // 105 | // void recoverTree(TreeNode* root) { 106 | // 107 | // if (root == NULL) { 108 | // return; 109 | // } 110 | // 111 | // vector seq; 112 | // inorder(root, seq); 113 | // 114 | // int len = seq.size(); 115 | // TreeNode* ptr1 = NULL; 116 | // TreeNode* ptr2 = NULL; 117 | // 118 | // for (int i = 0; i < len; i++) { 119 | // if (i + 1 < len && seq[i]->val > seq[i + 1]->val && ptr1 == NULL) { 120 | // ptr1 = seq[i]; 121 | // } 122 | // 123 | // if (i - 1 >= 0 && seq[i - 1] ->val > seq[i]->val) { 124 | // ptr2 = seq[i]; 125 | // } 126 | // } 127 | // 128 | // if (ptr1 != NULL && ptr2 != NULL) { 129 | // int tmp = ptr1->val; 130 | // ptr1->val = ptr2->val; 131 | // ptr2->val = tmp; 132 | // } 133 | // 134 | // return; 135 | // } 136 | //}; 137 | -------------------------------------------------------------------------------- /chapter 12/227 基本计算器2.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 227. Basic Calculator II 3 | 4 | class Solution { 5 | private: 6 | stack number; 7 | 8 | public: 9 | long calNumber(long x, long y, char op) { 10 | switch(op) { 11 | case '+': 12 | return x + y; 13 | case '-': 14 | return x - y; 15 | case '*': 16 | return x * y; 17 | case '/': 18 | return x / y; 19 | default: 20 | return INT_MIN; // throw error; 21 | } 22 | } 23 | 24 | long getNumber(string s, int pos, int& end) { 25 | // assert(begin >= 0); 26 | int len = s.size(); 27 | while (pos < len && s[pos] == ' ') { 28 | pos++; 29 | } 30 | 31 | long val = 0; 32 | while (pos < len && '0' <= s[pos] && s[pos] <= '9') { 33 | val = val * 10 + (s[pos] - '0'); 34 | pos++; 35 | } 36 | end = pos; 37 | return val; 38 | } 39 | 40 | int calculate(string s) { 41 | if (s.empty()) { 42 | // throw error 43 | return INT_MIN; 44 | } 45 | 46 | int i = 0; 47 | int len = s.size(); 48 | while (i < s.size()) { 49 | if (s[i] == ' ') { 50 | i++; 51 | continue; 52 | } 53 | 54 | if ('0' <= s[i] && s[i] <= '9') { 55 | int j = -1; 56 | int pos = i; 57 | 58 | // long val = getNumber(s, i, j); // call function may over time limit 59 | while (pos < len && s[pos] == ' ') { 60 | pos++; 61 | } 62 | 63 | long val = 0; 64 | while (pos < len && '0' <= s[pos] && s[pos] <= '9') { 65 | val = val * 10 + (s[pos] - '0'); 66 | pos++; 67 | } 68 | 69 | number.push(val); 70 | i = pos; 71 | continue; 72 | } 73 | 74 | if (s[i] == '+' || s[i] == '-') { 75 | int j = -1; 76 | // long val = getNumber(s, i + 1, j); 77 | int pos = i + 1; 78 | while (pos < len && s[pos] == ' ') { 79 | pos++; 80 | } 81 | 82 | long val = 0; 83 | while (pos < len && '0' <= s[pos] && s[pos] <= '9') { 84 | val = val * 10 + (s[pos] - '0'); 85 | pos++; 86 | } 87 | 88 | if (s[i] == '-') { 89 | number.push(-val); 90 | } else { 91 | number.push(val); 92 | } 93 | i = pos; 94 | continue; 95 | } 96 | 97 | if (s[i] == '*' || s[i] == '/') { 98 | // assert(!number.empty() && i < len - 1); 99 | char op = s[i]; 100 | long x = number.top(); 101 | number.pop(); 102 | 103 | int j = -1; 104 | // long y = getNumber(s, i + 1, j); 105 | int pos = i + 1; 106 | while (pos < len && s[pos] == ' ') { 107 | pos++; 108 | } 109 | 110 | long val = 0; 111 | while (pos < len && '0' <= s[pos] && s[pos] <= '9') { 112 | val = val * 10 + (s[pos] - '0'); 113 | pos++; 114 | } 115 | i = pos; 116 | 117 | int y = val; 118 | 119 | long k = calNumber(x, y, op); 120 | number.push(k); 121 | continue; 122 | } 123 | 124 | // assert not happend 125 | i++; 126 | } 127 | 128 | long sum = 0; 129 | while (!number.empty()) { 130 | sum += number.top(); 131 | number.pop(); 132 | } 133 | 134 | return sum; 135 | } 136 | }; 137 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## LeetCode 101 :和你一起轻松刷题 2 | 3 | ### 第 2 章 最易懂的贪心算法 4 | 5 | ##### 例题 6 | 7 | - [x] 455 分发饼干 8 | - [x] 135 分发糖果 9 | - [x] 435 无重叠区间 10 | 11 | ##### 练习 12 | 13 | - [x] 605 种花问题 14 | - [x] 452 用最少的数量引爆气球 15 | - [x] 763 划分字母区间 16 | - [x] 122 买股票的最佳时机2 17 | - [x] 406 根据身高重建队列 18 | - [x] 665 非递减数列 19 | 20 | **总结:分配问题、区间问题** 21 | 22 |   23 | 24 | ### 第 3 章 玩转双指针 25 | 26 | ##### **例题** 27 | 28 | - [x] 167 两数之和 2 29 | - [x] 88 合并两个有序数组 30 | - [x] 142 环形链表 2 31 | - [x] 76 最小覆盖字串 32 | 33 | ##### **练习** 34 | 35 | - [x] 633 平方数之和 36 | - [x] 680 验证回文字符串 37 | - [x] 524 通过删除字母匹配到字典里最长单词 38 | 39 | **总结:Two Sum、归并两个有序数组、快慢指针、滑动窗口** 40 | 41 |   42 | 43 | ### 第 4 章 居合斩!二分查找 44 | 45 | ##### 例题 46 | 47 | - [x] 69 x 的平方根 48 | - [x] 34 在排序数组中查找元素的第一个和最后一个位置 49 | - [x] 81 搜索旋转排序数组2 50 | 51 | ##### 练习 52 | 53 | - [x] 154 寻找旋转排序数组中的最小值 54 | - [x] 540 有序数组中的单一元素 55 | - [x] 4 寻找两个有序数组的中位数 56 | 57 | **总结:求开方(牛顿迭代法)、查找区间、旋转数组查找数字** 58 | 59 |   60 | 61 | ### 第 5 章 千奇百怪的排序算法 62 | 63 | ##### 例题 64 | 65 | - [x] 215 数组中的第K个最大元素 66 | - [x] 347 前K个高频元素 67 | 68 | ##### 练习 69 | 70 | - [x] 451 根据字符出现的频率排序 71 | - [x] 75 颜色分类(经典荷兰国旗问题) 72 | 73 | **总结:常用排序算法、快速排序、选择排序、桶排序** 74 | 75 |   76 | 77 | ### 第 6 章 一切皆可搜索 78 | 79 | ##### **例题** 80 | 81 | - [x] 695 岛屿的最大面积 82 | - [x] 547 省份数量 83 | - [x] 417 太平洋大西洋水流问题 84 | - [x] 46 全排列 85 | - [x] 77 全组合 86 | - [x] 79 单词搜索 87 | - [x] 51 N-皇后问题 88 | - [x] 934 最短的桥 89 | - [ ] 126 单词接龙2 90 | 91 | ##### 练习 92 | 93 | - [x] 130 被环绕的区域 94 | - [x] 257 二叉树的所有路径 95 | - [x] 47 全排列2 96 | - [x] 40 全组合2 97 | - [ ] 37 解数独 (不会玩儿数独 ~ 下次一定!) 98 | - [x] 310 最小高度树 99 | 100 | **总结:深度优先搜索、回溯法、广度优先搜索** 101 | 102 |   103 | 104 | ### 第 7 章 深入浅出动态规划 105 | 106 | ##### 基本动态规划:一维 107 | 108 | - [x] 70 爬楼梯 109 | - [x] 198 打家劫舍 110 | - [x] 413 等差数列划分 111 | 112 | ##### 基本动态规划:二维 113 | 114 | - [x] 64 最小路径和 115 | - [x] 542 01矩阵 116 | - [x] 221 最大正方形 117 | 118 | ##### 分割类型题 119 | 120 | - [x] 279 完全平方数 121 | - [x] 91 解码方法 122 | - [x] 139 单词拆分 123 | 124 | ##### 子序列问题 125 | 126 | - [x] 300 最长递增子序列 127 | - [x] 1143 最长公共子序列 128 | 129 | ##### 背包问题 130 | 131 | - [x] 416 分割等和子集 132 | - [x] 474 零和一 133 | - [x] 322 零钱兑换 134 | 135 | ##### 字符串编辑 136 | 137 | - [x] 72 编辑距离 138 | - [x] 650 只有两个键的键盘 139 | - [x] 10 正则表达式匹配 140 | 141 | ##### 股票交易 142 | 143 | - [x] 121 买卖股票的最佳时机 144 | - [x] 188 买卖股票的最佳时机4 145 | - [x] 309 买卖股票的最佳时机含冷冻期 146 | 147 | ##### 练习 148 | 149 | - [x] 213 打家劫舍2 150 | - [x] 53 最大子序和 151 | - [x] 343 整数分解 152 | - [x] 583 两个字符串的删除操作 153 | - [x] 646 最长数对链 154 | - [x] 376 最长摇摆子序列 155 | - [x] 494 目标和 156 | - [x] 714 买卖股票的最佳时机含手续费 157 | 158 |   159 | 160 | ### 第 8 章 化繁为简的分治法 161 | 162 | ##### 例题与练习 163 | 164 | - [x] 241 为运算表达式设计优先级 165 | 166 | - [x] 932 漂亮数组 (这技巧不看题解哪里能想得到~ ) 167 | 168 | - [x] 312 戳气球 169 | 170 | 171 |   172 | 173 | ### 第 9 章 巧解数学问题 174 | 175 | ##### 例题 176 | 177 | - [x] 204 计数质数 178 | - [x] 504 7进制数 179 | - [x] 172 阶乘后的0 180 | - [x] 415 字符串相加 181 | - [x] 326 3的幂 182 | - [x] 384 打乱数组 183 | - [x] 528 按权重随机选择 184 | - [x] 382 链表随机节点 185 | 186 | ##### 练习 187 | 188 | - [x] 168 Excel 表列名称 189 | - [x] 67 二进制求和 190 | - [x] 238 除自身以外数组的乘积 191 | - [x] 462 最少移动次数使元素相等 192 | - [x] 169 多数元素(Boyer-Moore Majority Vote,下次一定) 193 | - [ ] 470 用rand7 实现 rand10 (拒绝采样,下次一定) 194 | - [ ] 202 快乐数 (数学证明,下次一定) 195 | 196 |   197 | 198 | ### 第 10 章 神奇的位运算 199 | 200 | ##### 例题 201 | 202 | - [x] 461 汉明距离 203 | - [x] 190 颠倒二进制位 204 | - [x] 136 只出现一次的数字 205 | - [x] 342 4的幂 206 | - [x] 318 最大单词长度乘积 207 | - [x] 338 比特位计数 208 | 209 | ##### 练习 210 | 211 | - [x] 268 丢失的数字 212 | - [x] 693 交替位二进制数 213 | - [x] 476 数字的补数 214 | - [x] 260 只出现一次的数字3 215 | 216 |   217 | 218 | ### 第 11 章 妙用数据结构 219 | 220 | ##### 数组 221 | 222 | - [x] 448 找到所有数组中消失的数字 223 | - [x] 48 旋转图像 224 | - [x] 240 搜索二维数组 225 | - [x] 769 最多能完成排序的块 226 | 227 | ##### 栈和队列 228 | 229 | - [x] 232 用队列实现栈 230 | - [x] 155 最小栈 231 | - [x] 20 有效的括号 232 | 233 | ##### 单调栈和优先队列 234 | 235 | - [x] 739 每日温度 236 | - [x] 23 合并K个升序链表 237 | - [ ] 218 天际线问题 238 | 239 | ##### 双端队列和哈希表 240 | 241 | - [x] 239 滑动窗口最大值 242 | - [x] 1 两数之和 243 | - [x] 128 最长连续序列 244 | - [x] 149 直线上最多的点数 245 | 246 | ##### 多重集合、前缀和与积分图 247 | 248 | - [ ] 332 重新安排行程(Oh ~ 求解欧拉路径,下次一定!) 249 | - [x] 303 区域和检索-数组不可变 250 | - [x] 304 二维区域和检索-矩阵不可变 251 | - [x] 560 和为K的子数组 252 | 253 | ##### 练习 254 | 255 | - [x] 566 重塑矩阵 256 | - [x] 225 用栈实现队列 257 | - [x] 503 下一个更大元素2 258 | - [x] 217 存在重复元素 259 | - [x] 697 数组的度 260 | - [x] 594 最长和谐子序列 261 | - [x] 287 寻找重复数 262 | - [x] 313 超级丑数 263 | - [x] 870 优势洗牌 264 | - [ ] 307 区域和检索-数组可修改(Oh ~ 线段树,下次一定!) 265 | 266 |   267 | 268 | ### 第 12 章 令人头大的字符串 269 | 270 | ##### 例题 271 | 272 | - [x] 242 有效的字母异位词 273 | - [x] 205 同构字符串 274 | - [x] 647 回文字符串 275 | - [ ] 696 计数二进制子串(尴尬,没有读明白题) 276 | - [x] 227 基本计算器2 277 | - [ ] 28 实现strStr()(KMP算法,下次一定) 278 | 279 | ##### 练习 280 | 281 | - [x] 409 最长回文串 282 | - [x] 3 无重复字符的回文串 283 | - [ ] 772 基本计算器3(会员题,下次一定) 284 | - [x] 5 最长回文子串 285 | 286 |   287 | 288 | ### 第 13 章 指针三剑客之一:链表 289 | 290 | ##### 例题 291 | 292 | - [x] 206 反转链表 293 | - [x] 21 合并两个有序链表 294 | - [x] 24 两两交换链表中的节点 295 | - [x] 160 相交链表 296 | - [x] 234 回文链表 297 | 298 | ##### 练习 299 | 300 | - [x] 83 删除排序链表中的重复元素 301 | - [x] 328 奇偶链表 302 | - [x] 19 删除链表的倒数第n个节点 303 | - [x] 148 排序链表 304 | 305 |   306 | 307 | ### 第 14 章 指针三剑客之二:树 308 | 309 | ##### 树的递归 310 | 311 | - [x] 104 二叉树的最大深度 312 | - [x] 110 平衡二叉树 313 | - [x] 543 二叉树的直径 314 | - [x] 437 路径总和3 315 | - [x] 101 对称二叉树 316 | - [x] 1110 删点成林 317 | 318 | ##### 层次遍历和前中后序遍历 319 | 320 | - [x] 637 二叉树的层平均值 321 | - [x] 105 从前序和中序遍历序列构造二叉树 322 | - [x] 144 二叉树的前序遍历(迭代) 323 | 324 | ##### 二叉搜索树和字典树 325 | 326 | - [x] 99 恢复二叉搜索树 327 | - [x] 669 修剪二叉搜索树 328 | - [x] 208 实现前缀树(Trie) 329 | 330 | ##### 练习 331 | 332 | - [x] 226 翻转二叉树 333 | - [x] 617 合并二叉树 334 | - [x] 572 另一棵树的子树 335 | - [x] 404 左叶子之和 336 | - [x] 513 找树左下角的值 337 | - [x] 538 把二叉树转化为累加树 338 | - [x] 235 二叉搜索树的最近公共祖先 339 | - [x] 530 二叉搜索树的最小绝对差 340 | - [x] 889 从前序和后序遍历序列构造二叉树 341 | - [x] 106 从中序和后序遍历序列构造二叉树 342 | - [x] 94 二叉树的中序遍历(迭代) 343 | - [x] 145 二叉树的后序遍历(迭代) 344 | - [x] 236 二叉树的最近公共祖先 345 | - [x] 109 将有序链表转化为二叉搜索树 346 | - [x] 897 递增顺序搜索树 347 | - [x] 653 两数之和4-输入BST 348 | - [x] 450 删除二叉搜索树中的节点 349 | 350 |   351 | 352 | ### 第 15 章 指针三剑客之三:图 353 | 354 | ##### 例题与练习 355 | 356 | - [ ] 785 判断二分图 357 | - [ ] 210 课程表2 358 | - [ ] 1059 从始点到终点的所有路径 359 | - [ ] 1135 最低成本联通所有城市 360 | - [ ] 882 细分图中的可到达节点 361 | 362 |   363 | 364 | ### 第 16 章 更加复杂的数据结构 365 | 366 | ##### 例题与练习 367 | 368 | - [x] 684 冗余连接 369 | - [x] 146 LRU 缓存 370 | - [ ] 1135 最低成本联通所有城市 371 | - [x] 380 常数时间插入删除和获取随机元素 372 | - [ ] 432 全O(1) 数据结构(十字链表) 373 | - [ ] 716 最大栈 -------------------------------------------------------------------------------- /chapter 6/310 最小高度树.cpp: -------------------------------------------------------------------------------- 1 | 2 | // 310. Minimum Height Trees 3 | 4 | // Multi-BFS 5 | class Solution { 6 | public: 7 | void transferEdges(const vector>& edges, vector >& connection) { 8 | if (edges.empty()) { 9 | return; 10 | } 11 | 12 | int len = edges.size(); 13 | 14 | // assert(connection.size() == len); 15 | // assert(connection[0].size() == len); 16 | for (int i = 0; i < len; i++) { 17 | int x = edges[i][0]; 18 | int y = edges[i][1]; 19 | connection[x].insert(y); 20 | connection[y].insert(x); 21 | } 22 | 23 | return; 24 | } 25 | 26 | int multiBFS(int n, vector >& connection, vector& root) { 27 | // assert... 28 | 29 | if (n == 0) { 30 | return 0; 31 | } 32 | 33 | if (n == 1) { 34 | root.push_back(0); 35 | return 1; 36 | } 37 | 38 | queue leafNodes; 39 | for (int i = 0; i < n; i++) { 40 | if (connection[i].size() == 1) { 41 | leafNodes.push(i); 42 | } 43 | } 44 | 45 | int visitedNum = 0; 46 | int level = 0; 47 | while (!leafNodes.empty()) { 48 | int num = leafNodes.size(); 49 | level ++; 50 | 51 | if (visitedNum >= n - 2) { 52 | while (!leafNodes.empty()) { 53 | int tmp = leafNodes.front(); 54 | leafNodes.pop(); 55 | root.push_back(tmp); 56 | } 57 | 58 | break; 59 | } 60 | 61 | while (num > 0) { 62 | int currNode = leafNodes.front(); 63 | leafNodes.pop(); 64 | visitedNum ++; 65 | num --; 66 | 67 | unordered_set::iterator it = connection[currNode].begin(); 68 | int connNode = *it; 69 | 70 | connection[currNode].clear(); 71 | connection[connNode].erase(currNode); 72 | if (connection[connNode].size() == 1) { 73 | leafNodes.push(connNode); 74 | } 75 | } 76 | 77 | } 78 | 79 | return level; 80 | } 81 | 82 | vector findMinHeightTrees(int n, vector>& edges) { 83 | // assert... 84 | vector root; 85 | 86 | vector > connection(n); 87 | transferEdges(edges, connection); 88 | 89 | int height = multiBFS(n, connection, root); 90 | return root; 91 | } 92 | }; 93 | 94 | 95 | 96 | 97 | // 310. Minimum Height Trees 98 | 99 | 100 | // BFS: over time 101 | //class Solution { 102 | //public: 103 | // void transferEdges(const vector>& edges, vector>& connection) { 104 | // if (edges.empty()) { 105 | // return; 106 | // } 107 | // 108 | // int len = edges.size(); 109 | // 110 | // // assert(connection.size() == len); 111 | // // assert(connection[0].size() == len); 112 | // for (int i = 0; i < len; i++) { 113 | // int x = edges[i][0]; 114 | // int y = edges[i][1]; 115 | // connection[x][y] = 1; 116 | // connection[y][x] = 1; 117 | // } 118 | // 119 | // return; 120 | // } 121 | // 122 | // int bfs(int i, const vector >& connection) { 123 | // // assert... 124 | // 125 | // int level = 0; 126 | // queue nodes; 127 | // vector used(connection.size(), false); 128 | // 129 | // nodes.push(i); 130 | // used[i] = true; 131 | // 132 | // while (!nodes.empty()) { 133 | // int num = nodes.size(); 134 | // if (num == 0) { 135 | // break; 136 | // } 137 | // 138 | // while (num > 0) { 139 | // int curr = nodes.front(); 140 | // nodes.pop(); 141 | // num--; 142 | // 143 | // for (int j = 0; j < connection[0].size(); j++) { 144 | // if (j != curr && connection[curr][j] == 1 && !used[j]) { 145 | // nodes.push(j); 146 | // used[j] = true; 147 | // } 148 | // } 149 | // } 150 | // 151 | // level ++; 152 | // } 153 | // 154 | // return level; 155 | // } 156 | // 157 | // vector findMinHeightTrees(int n, vector>& edges) { 158 | // // assert... 159 | // vector root; 160 | // 161 | // vector > connection(n, vector (n, 0)); 162 | // transferEdges(edges, connection); 163 | // 164 | // 165 | // int minHeight = n + 1; 166 | // 167 | // for (int i = 0; i < n; i++) { 168 | // int path = bfs(i, connection); 169 | // 170 | // if (path == minHeight) { 171 | // root.push_back(i); 172 | // } else if (path < minHeight) { 173 | // minHeight = path; 174 | // root.clear(); 175 | // root.push_back(i); 176 | // } 177 | // } 178 | // 179 | // return root; 180 | // } 181 | //}; 182 | 183 | 184 | 185 | 186 | 187 | // DFS: over time 188 | 189 | //class Solution { 190 | //public: 191 | // void transferEdges(const vector>& edges, vector>& connection) { 192 | // if (edges.empty()) { 193 | // return; 194 | // } 195 | // 196 | // int len = edges.size(); 197 | // 198 | // // assert(connection.size() == len); 199 | // // assert(connection[0].size() == len); 200 | // for (int i = 0; i < len; i++) { 201 | // int x = edges[i][0]; 202 | // int y = edges[i][1]; 203 | // connection[x][y] = 1; 204 | // connection[y][x] = 1; 205 | // } 206 | // 207 | // return; 208 | // } 209 | // 210 | // int dfs(int i, vector& used, const vector>& connection) { 211 | // // assert... 212 | // 213 | // int height = 1; 214 | // int maxPath = 0; 215 | // int len = connection.size(); 216 | // 217 | // used[i] = true; 218 | // for (int j = 0; j < len; j++) { 219 | // if (i != j && connection[i][j] == 1 && !used[j]) { 220 | // maxPath = max(maxPath, dfs(j, used, connection)); 221 | // } 222 | // } 223 | // 224 | // used[i] = false; 225 | // height = maxPath + 1; 226 | // return height; 227 | // } 228 | // 229 | // vector findMinHeightTrees(int n, vector>& edges) { 230 | // // assert... 231 | // vector root; 232 | // vector used(n, false); 233 | // vector > connection(n, vector (n, 0)); 234 | // transferEdges(edges, connection); 235 | // 236 | // 237 | // int minHeight = n + 1; 238 | // 239 | // for (int i = 0; i < n; i++) { 240 | // int path = dfs(i, used, connection); 241 | // 242 | // if (path == minHeight) { 243 | // root.push_back(i); 244 | // } else if (path < minHeight) { 245 | // minHeight = path; 246 | // root.clear(); 247 | // root.push_back(i); 248 | // } 249 | // } 250 | // 251 | // return root; 252 | // } 253 | //}; 254 | --------------------------------------------------------------------------------