from LeetCode Hot100 and CodeTop
文章目录
- 3. 无重复字符的最长子串
- 206. 反转链表
- 146. LRU缓存机制
- 215. 数组中的第K个最大元素
- 25. K 个一组翻转链表
- 15. 三数之和
- 53. 最大子序和
- 补充题4. 手撕快速排序
- 21. 合并两个有序链表
- 1. 两数之和
- 102. 二叉树的层序遍历
- 33. 搜索旋转排序数组
- 5. 最长回文子串
- 20. 有效的括号
- 121. 买卖股票的最佳时机
- 141. 环形链表
- 88. 合并两个有序数组
- 200. 岛屿数量
- 236. 二叉树的最近公共祖先
- 103. 二叉树的锯齿形层次遍历
- 46. 全排列
- 54. 螺旋矩阵
- 160. 相交链表
- 92. 反转链表 II
- 23. 合并K个排序链表
- 415. 字符串相加
- 300. 最长上升子序列
- 142. 环形链表 II
- 42. 接雨水
- 143. 重排链表
- 124. 二叉树中的最大路径和
- 19. 删除链表的倒数第 N 个结点
- 94. 二叉树的中序遍历
- 232. 用栈实现队列
- 72. 编辑距离
- 704. 二分查找
- 56. 合并区间
- 4. 寻找两个正序数组的中位数
- 1143. 最长公共子序列
- 199. 二叉树的右视图
- 82. 删除排序链表中的重复元素 II
- 31. 下一个排列
- 93. 复原IP地址
- 148. 排序链表
- 70. 爬楼梯
- 69. x 的平方根
- 2. 两数相加
- 22. 括号生成
- 8. 字符串转换整数 (atoi)
- 239. 滑动窗口最大值
- 41. 缺失的第一个正数
- 剑指 Offer 22. 链表中倒数第k个节点
- 165. 比较版本号
- 76. 最小覆盖子串
- 78. 子集
- 322. 零钱兑换
- 32. 最长有效括号
- 105. 从前序与中序遍历序列构造二叉树
- 155. 最小栈
- 43. 字符串相乘
- 151. 翻转字符串里的单词
- 32. 最长有效括号
- 144. 二叉树的前序遍历
- 110. 平衡二叉树
- 101. 对称二叉树
- 104. 二叉树的最大深度
- 129. 求根到叶子节点数字之和
- 543. 二叉树的直径
- 98. 验证二叉搜索树
- 113. 路径总和 II
- 470. 用 Rand7() 实现 Rand100()
- 64. 最小路径和
- 39. 组合总和
- 48. 旋转图像
- 394. 字符串解码
- 234. 回文链表
- 112. 路径总和
- 34. 在排序数组中查找元素的最后一个位置
- 221. 最大正方形
- 240. 搜索二维矩阵 II
- 169. 多数元素
3. 无重复字符的最长子串
3. 无重复字符的最长子串
for + while 版的双指针代码
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size() == 0 || s.size() == 1) return s.size();
int n = s.size(), ret = 1;
unordered_map<int, int> umap;
for (int i = 0, j = 0; i < n; i ++) {
while (j < n && umap[s[j]] == 0) {
umap[s[j++]] ++;
ret = max(ret, j - i);
}
umap[s[i]] --;
}
return ret;
}
};
206. 反转链表
- 迭代
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* ret = NULL;
while(head) {
ListNode* tmp = head -> next;
head -> next = ret;
ret = head;
head = tmp;
}
return ret;
}
};
- 递归
class Solution {
public:
ListNode* rever(ListNode* head, ListNode* tmp) {
if(!head) return tmp;
ListNode* curr = head -> next;
head -> next = tmp;
return rever(curr, head);
}
ListNode* reverseList(ListNode* head) {
return rever(head, NULL);
}
};
146. LRU缓存机制
class LRUCache {
public:
// 定义双链表
struct Node {
int key, value;
Node* left, *right;
Node(int _key, int _value) : key(_key), value(_value), left(NULL), right(NULL) {}
}*L, *R;
int n;
unordered_map<int, Node*> umap;
LRUCache(int capacity) {
n = capacity;
L = new Node(-1, -1);
R = new Node(-1, -1);
L -> right = R;
R -> left = L;
}
int get(int key) {
if (umap.count(key) == 0) return -1;
auto p = umap[key];
remove(p);
insert(p);
return p->value;
}
void put(int key, int value) {
if (umap.count(key)) {
auto p = umap[key];
p -> value = value;
remove(p);
insert(p);
} else {
if (umap.size() == n) {
auto p = R -> left;
remove(p);
umap.erase(p->key);
delete p;
}
auto p = new Node(key, value);
umap[key] = p;
insert(p);
}
}
void remove(Node* p) {
p->left->right = p->right;
p->right->left = p->left;
}
void insert(Node* p) {
L->right->left = p;
p->right = L->right;
p->left = L;
L->right = p;
}
};
215. 数组中的第K个最大元素
class Solution {
public:
int target;
int quickSort(vector<int>& nums, int left, int right) {
if (left == right) return nums[left];
int i = left - 1, j = right + 1, q = nums[left + right >> 1];
while(i < j) {
do i ++; while(nums[i] < q);
do j --; while(nums[j] > q);
if(i < j) swap(nums[i], nums[j]);
}
if(j >= target) return quickSort(nums, left, j);
else return quickSort(nums, j + 1, right);
}
int findKthLargest(vector<int>& nums, int k) {
target = nums.size() - k;
return quickSort(nums, 0, nums.size() - 1);
}
};
25. K 个一组翻转链表
class Solution {
public:
void reverse(ListNode* preleft, int t) {
ListNode* end = preleft;
for(int i = 0; i < t; i ++) {
end = end -> next;
}
ListNode* curr = preleft -> next;
preleft -> next = end -> next;
for(int i = 0; i < t; i ++) {
ListNode* tmp = curr -> next;
curr -> next = preleft -> next;
preleft -> next = curr;
curr = tmp;
}
}
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* p = head;
ListNode* hair = new ListNode(0);
hair -> next = head;
ListNode* preleft = hair;
int cnt = 0;
while(p) {
cnt ++;
if (cnt == k) {
reverse(preleft, k);
for(int i = 0; i < k - 1; i ++){
p = p -> next;
}
preleft = p;
cnt = 0;
} p = p -> next;
}
return hair -> next;
}
};
15. 三数之和
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ret;
int n = nums.size();
if (n < 3) return ret;
sort(nums.begin(), nums.end());
for (int i = 0; i < n - 2; i ++) {
if (i > 0 && nums[i] == nums[i - 1]) continue;
int l = i + 1, r = n - 1;
while (l < r) {
if (nums[i] + nums[l] + nums[r] < 0) l ++;
else if (nums[i] + nums[l] + nums[r] > 0) r--;
else {
ret.push_back({nums[i], nums[l], nums[r]});
while(l < r && nums[r] == nums[r - 1]) r --;
while(l < r && nums[l] == nums[l + 1]) l ++;
l ++, r --;
}
}
}
return ret;
}
};
53. 最大子序和
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int pre=0, ret=-1e6;
for(int i=0; i<nums.size(); i++) {
pre = max(pre+nums[i], nums[i]);
ret = max(ret, pre);
}
return ret;
}
};
补充题4. 手撕快速排序
class Solution {
public:
void quick_sort(vector<int>& q, int left, int right)
{
if (left >= right) return;
int mid = rand()%(right - left + 1) + left;
int i = left - 1, j = right + 1, x = q[mid];
while (i < j)
{
do i ++ ; while (q[i] < x);
do j -- ; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, left, j), quick_sort(q, j + 1, right);
}
vector<int> sortArray(vector<int>& nums) {
srand(time(0));
quick_sort(nums, 0, nums.size() - 1);
return nums;
}
};
21. 合并两个有序链表
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
if(!list1 || !list2) return !list1 ? list2 : list1;
ListNode* head = new ListNode(0);
ListNode* h = head;
while(list1 && list2) {
if (list1 -> val < list2 -> val) {
h -> next = list1;
list1 = list1 -> next;
} else {
h -> next = list2;
list2 = list2 -> next;
}
h = h -> next;
}
if (list1) h -> next = list1;
if (list2) h -> next = list2;
return head -> next;
}
};
1. 两数之和
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> umap;
for(int i =0; i < nums.size(); i ++){
auto f = umap.find(target - nums[i]);
if(f!=umap.end()) {
return {f->second, i};
}
umap[nums[i]] = i;
}
return {};
}
};
102. 二叉树的层序遍历
class Solution {
public:
vector<vector<int>> ret;
void dfs(TreeNode* root, int level) {
if (!root) return;
if (ret.size() < level) {
ret.push_back({root -> val});
} else {
ret[level - 1].push_back({root -> val});
}
if(root -> left) dfs(root -> left, level + 1);
if(root -> right) dfs(root -> right, level + 1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
dfs(root, 1);
return ret;
}
};
33. 搜索旋转排序数组
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while(left < right) {
int mid = left + right >> 1;
if (nums[left] == target) return left;
else if (nums[right] == target) return right;
else if (nums[mid] == target) return mid;
else if (nums[left] < nums[mid]) {
if (nums[mid] > target && nums[left] < target) right = mid;
else left = mid + 1;
} else {
if (nums[mid] < target && nums[left] > target) left = mid + 1;
else right = mid;
}
}
if (nums[left] == target) return left;
return -1;
}
};
5. 最长回文子串
class Solution {
public:
string longestPalindrome(string s) {
int ret = 1;
if (s.size() == 1) return s;
int left, right;
pair<int, int> loc;
for (int i = 0; i < s.size() - 1; i ++) {
left = i - 1, right = i + 1;
while(left >= 0 && right < s.size() && s[left] == s[right]) {
if (right - left + 1 > ret) {
loc.first = left, loc.second = right;
ret = right - left + 1;
}
left --;
right ++;
}
left = i, right = i + 1;
while(left >= 0 && right < s.size() && s[left] == s[right]) {
if (right - left + 1 > ret) {
loc.first = left, loc.second = right;
ret = right - left + 1;
}
left --;
right ++;
}
}
return ret == 1 ? s.substr(0, 1) : s.substr(loc.first, loc.second - loc.first + 1);
}
};
20. 有效的括号
class Solution {
public:
bool isValid(string s) {
if (s.size() < 2) return false;
stack<int> stk;
while(!stk.empty()) stk.pop();
for (int i = 0; i < s.size(); i ++) {
if (s[i] == ')') {
if (!stk.empty() && stk.top() == '(') stk.pop();
else return false;
}
else if (s[i] == ']') {
if (!stk.empty() && stk.top() == '[') stk.pop();
else return false;
}
else if (s[i] == '}') {
if (!stk.empty() && stk.top() == '{') stk.pop();
else return false;
}
else stk.push(s[i]);
}
if (stk.empty()) return true;
else return false;
}
};
121. 买卖股票的最佳时机
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size(), tmp = prices[n - 1], ret = 0;
for (int i = n - 2; i >= 0; i --) {
tmp = max(tmp, prices[i + 1]);
ret = max(ret, tmp - prices[i]);
}
return ret;
}
};
141. 环形链表
class Solution {
public:
bool hasCycle(ListNode *head) {
if (!head || !head -> next) return false;
ListNode* slow = head, *fast = head;
while (fast && fast -> next) {
slow = slow -> next, fast = fast -> next -> next;
if (slow == fast) return true;
}
return false;
}
};
88. 合并两个有序数组
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int p = m + n, p1 = m - 1, p2 = n - 1;
while(p --) {
if (p1 >= 0 && p2 >= 0) {
if (nums1[p1] >= nums2[p2]) nums1[p] = nums1[p1 --];
else nums1[p] = nums2[p2 --];
} else if (p1 >= 0) nums1[p] = nums1[p1 --];
else nums1[p] = nums2[p2 --];
}
}
};
200. 岛屿数量
class Solution {
public:
void dfs (vector<vector<char>>& grid, int x, int y, int from) {
if (grid[x][y] != '1') return;
grid[x][y] = '0';
if (from != 2 && y + 1 < grid[0].size() && grid[x][y + 1] == '1') dfs(grid, x, y + 1, 4);
if (from != 3 && x + 1 < grid.size() && grid[x + 1][y] == '1') dfs(grid, x + 1, y, 1);
if (from != 4 && y - 1 >= 0 && grid[x][y - 1] == '1') dfs(grid, x, y - 1, 2);
if (from != 1 && x - 1 >= 0 && grid[x - 1][y] == '1') dfs(grid, x - 1, y, 3);
}
int numIslands(vector<vector<char>>& grid) {
int cnt = 0;
for (int i = 0; i < grid.size(); i ++) {
for (int j = 0; j < grid[0].size(); j ++) {
if (grid[i][j] == '1') {
dfs(grid, i, j, -1);
cnt += 1;
}
}
}
return cnt;
}
};
236. 二叉树的最近公共祖先
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == p || root == q || root == NULL) return root;
TreeNode* left = lowestCommonAncestor(root -> left, p, q);
TreeNode* right = lowestCommonAncestor(root -> right, p, q);
if(left != NULL && right != NULL) return root;
else if (left != NULL) return left;
else return right;
}
};
103. 二叉树的锯齿形层次遍历
class Solution {
public:
vector<vector<int>> ret;
void dfs(TreeNode* root, int level) {
if (!root) return;
if (ret.size() < level) ret.push_back({root -> val});
else if (level % 2 == 1) ret[level - 1].push_back(root -> val);
else ret[level - 1].insert(ret[level - 1].begin(), root -> val);
if(root -> left) dfs(root -> left, level + 1);
if(root -> right) dfs(root -> right, level + 1);
}
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
dfs(root, 1);
return ret;
}
};
46. 全排列
class Solution {
public:
vector<vector<int>> ret;
void fulllist(vector<vector<int>>& ret, vector<int>& nums, int idx, int len) {
if (len == idx) {
ret.push_back(nums);
return;
}
for (int i = idx; i < len; i ++) {
swap(nums[i], nums[idx]);
fulllist(ret, nums, idx + 1, nums.size());
swap(nums[i], nums[idx]);
}
}
vector<vector<int>> permute(vector<int>& nums) {
if (nums.size() == 1) return {nums};
fulllist(ret, nums, 0, nums.size());
return ret;
}
};
54. 螺旋矩阵
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> ret;
if (matrix.empty()) return ret;
int left = 0, right = matrix[0].size() - 1;
int top = 0, bot = matrix.size() - 1;
while(true) {
for(int i = left; i <= right; i ++) ret.emplace_back(matrix[top][i]);
if (++ top > bot) break;
for(int i = top; i <= bot; i ++) ret.emplace_back(matrix[i][right]);
if (-- right < left) break;
for(int i = right; i >= left; i --) ret.emplace_back(matrix[bot][i]);
if (-- bot < top) break;
for(int i = bot; i >= top; i --) ret.emplace_back(matrix[i][left]);
if (++ left > right) break;
}
return ret;
}
};
160. 相交链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* tmpA = headA, *tmpB = headB;
int lenA = 0, lenB = 0;
while(tmpA && tmpB) {
lenA ++;
lenB ++;
tmpA = tmpA -> next;
tmpB = tmpB -> next;
}
if (tmpA) {
while(tmpA) {
lenA ++;
tmpA = tmpA -> next;
}
} else if (tmpB) {
while(tmpB) {
lenB ++;
tmpB = tmpB -> next;
}
}
tmpA = headA, tmpB = headB;
if (lenA > lenB) {
while(lenA > lenB) {
tmpA = tmpA -> next;
lenA --;
}
} else {
while(lenA < lenB) {
tmpB = tmpB -> next;
lenB --;
}
}
while(tmpA) {
if (tmpA == tmpB) return tmpA;
else {
tmpA = tmpA -> next;
tmpB = tmpB -> next;
}
}
return NULL;
}
};
92. 反转链表 II
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
if (left == right) return head;
// 从头开始会报错,所以需要 new 一个新的 head
ListNode* pre = new ListNode(0);
pre -> next = head;
ListNode* tmp = pre, *n;
int idx = 0, cnt = right - left + 1;
while(++ idx < left) tmp = tmp -> next;
ListNode* reverP = tmp -> next;
tmp -> next = NULL;
while(cnt --) {
n = reverP -> next;
reverP -> next = tmp -> next;
tmp -> next = reverP;
reverP = n;
}
while(tmp -> next) tmp = tmp -> next;
tmp -> next = reverP;
return pre -> next;
}
};
23. 合并K个排序链表
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
if(!list1 || !list2) return list1 ? list1 : list2;
ListNode* p1 = list1, *p2 = list2;
ListNode* ret = new ListNode(0);
ListNode* tmp = ret;
while(list1 && list2) {
if (list1 -> val < list2 -> val) {
tmp -> next = list1;
list1 = list1 -> next;
} else {
tmp -> next = list2;
list2 = list2 -> next;
}
tmp = tmp -> next;
}
tmp -> next = list1 ? list1 : list2;
return ret -> next;
}
ListNode* merge(vector<ListNode*>& lists, int left, int right) {
if (left == right) return lists[left];
else if(left > right) return NULL;
int mid = left + right >> 1;
return mergeTwoLists(merge(lists, left, mid), merge(lists, mid + 1, right));
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
return merge(lists, 0, lists.size() - 1);
}
};
415. 字符串相加
class Solution {
public:
string addStrings(string num1, string num2) {
int l1 = num1.size() - 1, l2 = num2.size() - 1, add = 0;
string ret = "";
while(l1 >= 0 || l2 >= 0 || add != 0) {
int a = l1 >= 0 ? num1[l1] - '0' : 0;
int b = l2 >= 0 ? num2[l2] - '0' : 0;
int sum = a + b + add;
ret.push_back(sum % 10 + '0');
add = sum / 10;
l1 --;
l2 --;
}
reverse(ret.begin(), ret.end());
return ret;
}
};
300. 最长上升子序列
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n = nums.size(), ret = 1;
if (n < 2) return n;
vector<int> f(n, 1);
for (int i = 0; i < n; i ++) {
for (int j = 0; j < i; j ++) {
if (nums[i] > nums[j]) f[i] = max(f[i], f[j] + 1);
}
ret = max(ret, f[i]);
}
return ret;
}
};
142. 环形链表 II
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if (!head || !head -> next) return NULL;
ListNode* slow = head, *fast = head;
while(fast -> next && fast -> next -> next) {
fast = fast -> next -> next;
slow = slow -> next;
if(fast == slow) {
slow = head;
while(slow != fast) {
slow = slow -> next;
fast = fast -> next;
}
return fast;
}
}
return NULL;
}
};
42. 接雨水
class Solution {
public:
int trap(vector<int>& height) {
int n = height.size(), ret = 0;
vector<int> max_left(n);
vector<int> max_right(n);
max_left[0] = height[0];
max_right[n - 1] = height[n - 1];
for(int i = 1; i < n; i ++) max_left[i] = max(max_left[i - 1], height[i]);
for(int i = n - 2; i >= 0; i --) max_right[i] = max(max_right[i + 1], height[i]);
for (int i = 1; i < n - 1; i ++) {
int tmp = min(max_left[i], max_right[i]) - height[i];
if(tmp > 0) ret += tmp;
}
return ret;
}
};
143. 重排链表
class Solution {
public:
void reorderList(ListNode* head) {
int n = 0, i = 0;
unordered_map<int, ListNode*> umap;
ListNode* tmp = head, *rec;
while(tmp) {
rec = tmp -> next;
umap[n ++] = tmp;
tmp -> next = NULL;
tmp = rec;
}
if (n == 1) return ;
tmp = head;
tmp -> next = umap[n - 1 - i];
i = 1;
tmp = tmp -> next;
while(i < n / 2) {
tmp -> next = umap[i];
tmp -> next -> next = umap[n - 1 - i];
tmp = tmp -> next -> next;
i ++;
}
if(n % 2 == 1) tmp -> next = umap[i];
}
};
124. 二叉树中的最大路径和
class Solution {
public:
int ret = -1e7;
int dfs(TreeNode* node) {
if (node == NULL) return 0;
int left = max(dfs(node -> left), 0);
int right = max(dfs(node -> right), 0);
int tmp = node -> val + left + right;
ret = max(ret, tmp);
return node -> val + max(left, right);
}
int maxPathSum(TreeNode* root) {
dfs(root);
return ret;
}
};
19. 删除链表的倒数第 N 个结点
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* fast = head, *slow = head;
for(int i = 0; i < n; i ++) fast = fast -> next;
if(!fast) return head -> next;
while(fast -> next) {
slow = slow -> next;
fast = fast -> next;
}
slow -> next = slow -> next -> next;
return head;
}
};
94. 二叉树的中序遍历
94. 二叉树的中序遍历
递归做法
class Solution {
public:
vector<int> ret;
void inorder(TreeNode* root) {
if(!root) return;
if(root -> left) inorder(root -> left);
ret.push_back(root -> val);
if(root -> right) inorder(root -> right);
}
vector<int> inorderTraversal(TreeNode* root) {
inorder(root);
return ret;
}
};
非递归做法
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode*> stk;
vector<int> res;
while(root || !stk.empty()) {
while(root) {
stk.push(root);
root = root -> left;
}
res.push_back(stk.top() -> val);
root = stk.top() -> right;
stk.pop();
}
return res;
}
};
232. 用栈实现队列
class MyQueue {
private:
stack<int> s1, s2;
void reverseStack() {
while(!s1.empty()) {
s2.push(s1.top());
s1.pop();
}
}
public:
MyQueue() {}
void push(int x) {
s1.push(x);
}
int pop() {
if(s2.empty()) reverseStack();
int x = s2.top();
s2.pop();
return x;
}
int peek() {
if (s2.empty()) reverseStack();
return s2.top();
}
bool empty() {
return s1.empty() && s2.empty();
}
};
72. 编辑距离
class Solution {
public:
int minDistance(string word1, string word2) {
int n = word1.size(), m = word2.size();
if (n * m == 0) return n + m;
vector<vector<int>> dp(n + 1, vector<int>(m + 1));
for (int i = 0; i < n + 1; i ++) dp[i][0] = i;
for (int j = 0; j < m + 1; j ++) dp[0][j] = j;
for (int i = 1; i < n + 1; i ++) {
for (int j = 1; j < m + 1; j ++) {
int pre = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
int left_down = word1[i - 1] == word2[j - 1] ? dp[i - 1][j - 1] : dp[i - 1][j - 1] + 1;
dp[i][j] = min(pre, left_down);
}
}
return dp[n][m];
}
};
704. 二分查找
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
if(nums[left] == target) return left;
else if(nums[right] == target) return right;
int ret;
while(left < right) {
int mid = left + right >> 1;
if (nums[mid] == target) return mid;
else if(nums[mid] > target) right = mid;
else left = mid + 1;
}
return -1;
}
};
56. 合并区间
bool cmp(vector<int>& a, vector<int>& b) {
return a[0] < b[0];
}
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
int n = intervals.size(), i = 0, loc;
if (n < 2) return intervals;
sort(intervals.begin(), intervals.end(), cmp);
vector<int> tmp;
vector<vector<int>> ret;
while(i < n) {
tmp = intervals[i];
loc = i + 1;
while(loc < n && intervals[loc][0] <= tmp[1]) {
tmp[1] = max(tmp[1], intervals[loc][1]);
loc ++;
}
ret.push_back(tmp);
i = loc;
}
return ret;
}
};
4. 寻找两个正序数组的中位数
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size() + nums2.size();
int i = 0, j = 0, tag = 0;
int tmp = n % 2 == 0?n/2-1:n/2;
while(tag < tmp) {
//均未走到末端
if(i < nums1.size() && j < nums2.size()) {
if(nums1[ i ] < nums2[ j ]) i++;
else j++;
}
//i走到最末端
else if(i >= nums1.size()) j++;
//j走到最末端
else i++;
tag++;
}
double ret = 0;
if(n % 2 == 0) tag = 2;
else tag = 1;
while(tag--) {
if(i < nums1.size() && j < nums2.size()) {
if(nums1[ i ] < nums2[ j ]) ret += nums1[ i++ ];
else ret += nums2[ j++ ];
}
else if(i >= nums1.size()) ret += nums2[ j++ ];
else ret += nums1[ i++ ];
}
if(n % 2 == 0) return ret / 2.0;
else return ret;
}
};
1143. 最长公共子序列
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
int n = text1.size(), m = text2.size();
vector<vector<int>> dp(n + 1, vector<int>(m + 1));
for (int i = 1; i < n + 1; i ++) {
for (int j = 1; j < m + 1; j ++) {
if (text1[i - 1] == text2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[n][m];
}
};
199. 二叉树的右视图
class Solution {
public:
vector<int> ret;
void dfs(TreeNode* root, int level) {
if (!root) return;
if (ret.size() < level) {
ret.push_back(root -> val);
} else {
ret[level - 1] = root -> val;
}
if (root -> left) dfs(root -> left, level + 1);
if (root -> right) dfs(root -> right, level + 1);
}
vector<int> rightSideView(TreeNode* root) {
dfs(root, 1);
return ret;
}
};
82. 删除排序链表中的重复元素 II
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (!head || !head -> next) return head;
ListNode* pre = new ListNode(0);
pre -> next = head;
ListNode* tmp = pre;
int num = -200;
while(tmp -> next -> next) {
if (tmp -> next -> val == tmp -> next -> next -> val) {
num = tmp -> next -> val;
tmp -> next = tmp -> next -> next;
} else if (tmp -> next -> val == num) {
tmp -> next = tmp -> next -> next;
} else tmp = tmp -> next;
}
if (tmp -> next -> val == num) {
tmp -> next = NULL;
}
return pre -> next;
}
};
31. 下一个排列
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int n = nums.size(), left = n - 2;
while(left >= 0 && nums[left] >= nums[left + 1]) {
left --;
}
if (left < 0) {
reverse(nums.begin(), nums.end());
} else {
int right = n - 1;
while(nums[right] <= nums[left]) {
right --;
}
swap(nums[left], nums[right]);
reverse(nums.begin() + left + 1, nums.end());
}
return;
}
};
93. 复原IP地址
class Solution {
public:
vector<string> ret;
void dfs(string& s, int start, int level) {
if (level == 3) {
if (isValid(s, start, s.size() - 1)) {
ret.push_back(s);
}
return ;
}
for (int i = start; i < s.size(); i ++) {
if (isValid(s, start, i)) {
s.insert(s.begin() + i + 1, '.');
dfs(s, i + 2, level + 1);
s.erase(s.begin() + i + 1);
}
else {
return;
}
}
}
bool isValid(string s, int start, int end) {
if (s[start] == '0' || start > end) {
return start == end;
}
int num = 0;
for (int i = start; i <= end; i ++) {
if (s[i] > '9' || s[i] < '0') {
return false;
}
num = num * 10 + (s[i] - '0');
if (num > 255) {
return false;
}
}
return true;
}
vector<string> restoreIpAddresses(string s) {
ret.clear();
if (s.size() < 4 || s.size() > 12) {
return ret;
}
dfs(s, 0, 0);
return ret;
}
};
148. 排序链表
class Solution {
public:
ListNode* merge(ListNode* ptr1, ListNode* ptr2) {
if (ptr1 == NULL || ptr2 == NULL) {
return ptr1 == NULL ? ptr2 : ptr1;
}
ListNode* ret;
if (ptr1 -> val < ptr2 -> val) {
ret = ptr1;
ptr1 = ptr1 -> next;
ret -> next = NULL;
} else {
ret = ptr2;
ptr2 = ptr2 -> next;
ret -> next = NULL;
}
ListNode* tmp = ret;
while(ptr1 && ptr2) {
if (ptr1 -> val < ptr2 -> val) {
tmp -> next = ptr1;
ptr1 = ptr1 -> next;
tmp = tmp -> next;
tmp -> next = NULL;
} else {
tmp -> next = ptr2;
ptr2 = ptr2 -> next;
tmp = tmp -> next;
tmp -> next = NULL;
}
}
if (ptr1) tmp -> next = ptr1;
if (ptr2) tmp -> next = ptr2;
return ret;
}
ListNode* lsort(ListNode* ptr) {
// split to (ptr, slow)
if (!ptr || !ptr -> next) {
return ptr;
}
ListNode* slow = ptr, *fast = ptr;
while(fast && fast -> next) {
fast = fast -> next -> next;
if (!fast || !fast -> next) {
ListNode* tmp = slow -> next;
slow -> next = NULL;
slow = tmp;
break;
}
slow = slow -> next;
}
// merge (ptr1, ptr2)
return merge(lsort(ptr), lsort(slow));
}
ListNode* sortList(ListNode* head) {
return lsort(head);
}
};
70. 爬楼梯
class Solution {
public:
int climbStairs(int n) {
if (n <= 2) return n;
vector<int> ret(n + 1);
ret[1] = 1, ret[2] = 2;
for (int i = 3; i <= n; i ++) {
ret[i] = ret[i - 1] + ret[i - 2];
}
return ret[n];
}
};
69. x 的平方根
class Solution {
public:
int mySqrt(int x) {
int left = 0, right = x, mid;
while(left < right) {
mid = (long long)left + right + 1 >> 1;
if (mid <= x / mid) left = mid;
else right = mid - 1;
}
return left;
}
};
2. 两数相加
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* head = NULL; ListNode* p = NULL;
int a = 0;
while(l1 != NULL && l2 != NULL) {
int sum = l1->val + l2->val + a;
if (p == NULL) {
p = new ListNode(sum%10);
} else {
p -> next = new ListNode(sum%10);
p = p -> next;
}
if (head == NULL) head = p;
l1 = l1 -> next; l2 = l2 -> next;
a = sum / 10;
}
while(l1 != NULL) {
int sum = l1->val + a;
p -> next = new ListNode(sum%10);
p = p -> next;
a = sum / 10;
l1 = l1 -> next;
}
while(l2 != NULL) {
int sum = l2->val + a;
p -> next = new ListNode(sum%10);
p = p -> next;
a = sum / 10;
l2 = l2 -> next;
}
if (a == 1) {
p -> next = new ListNode(1);
}
return head;
}
};
22. 括号生成
class Solution {
public:
vector<string> ret;
void dfs(string str, int l, int r, int n) {
if(l > n || r > n || r > l) return;
if(l == n && r == n) {ret.push_back(str); return;}
dfs(str + '(', l + 1, r, n);
dfs(str + ')', l, r + 1, n);
}
vector<string> generateParenthesis(int n) {
ret.clear();
dfs("", 0, 0, n);
return ret;
}
};
8. 字符串转换整数 (atoi)
class Solution {
public:
int myAtoi(string s) {
int sign = 1, tmp = 0, i = 0;
while(s[i] == ' ') ++i; //1.忽略前导空格
if(s[i] == '+' || s[i] == '-') //2.确定正负号
sign = (s[i++] == '-') ? -1 : 1; //s[i]为+的话sign依旧为1,为-的话sign为-1
while(s[i] >= '0' && s[i] <= '9') //3.检查输入是否合法
{
if(tmp > INT_MAX / 10 || (tmp == INT_MAX / 10 && s[i] - '0' > 7)) //4.是否溢出
return sign == 1 ? INT_MAX : INT_MIN;
tmp = tmp * 10 + (s[i++] - '0'); //5.不加括号有溢出风险
}
return tmp * sign;
}
};
239. 滑动窗口最大值
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
int n = nums.size();
vector<int> ans;
deque<int> idx;
for (int i = 0; i < n; i ++) {
if (!idx.empty() && i - k + 1 > idx.front()) {
idx.pop_front();
}
while (!idx.empty() && nums[idx.back()] < nums[i]) {
idx.pop_back();
}
idx.push_back(i);
if (i >= k - 1) {
ans.push_back(nums[idx.front()]);
}
}
return ans;
}
};
41. 缺失的第一个正数
class Solution {
public:
int firstMissingPositive(vector<int> &nums) {
int n = nums.size();
for (int i = 0; i < n; i ++) {
while (nums[i] != i + 1) {
if (nums[i] < 1 || nums[i] > n || nums[i] == nums[nums[i] - 1]) {
break;
}
int idx = nums[i] - 1;
nums[i] = nums[idx];
nums[idx] = idx + 1;
}
}
for (int i = 0; i < n; i ++) {
if (nums[i] != i + 1) return i + 1;
}
return n + 1;
}
};
剑指 Offer 22. 链表中倒数第k个节点
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode* slow, * fast;
slow = head, fast = head;
for (int i = 0; i < k; i ++) {
fast = fast -> next;
}
if (!fast) return slow;
while(fast) {
slow = slow -> next;
fast = fast -> next;
}
return slow;
}
};
165. 比较版本号
class Solution {
public:
int compareVersion(string version1, string version2) {
char cr;
int num1, num2;
istringstream istr1(version1);
istringstream istr2(version2);
while(bool(istr1 >> num1) + bool(istr2 >> num2)) {
if (num1 > num2) return 1;
else if (num1 < num2) return -1;
num1 = 0;
num2 = 0;
istr1 >> cr;
istr2 >> cr;
}
return 0;
}
};
76. 最小覆盖子串
78. 子集
class Solution {
public:
vector<vector<int>> ret;
vector<int> tmp;
void dfs(vector<int>& nums, int loc) {
if (loc > nums.size()) return;
else if (loc == nums.size()) {
ret.push_back(tmp);
return;
}
dfs(nums, loc + 1);
tmp.push_back(nums[loc]);
dfs(nums, loc + 1);
tmp.erase(tmp.end() - 1);
}
vector<vector<int>> subsets(vector<int>& nums) {
dfs(nums, 0);
return ret;
}
};
322. 零钱兑换
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
if (amount <= 0) return amount == 0 ? 0 : -1;
vector<int> dp(amount + 1);
for (int i = 0; i < amount + 1; i ++) {
dp[i] = 1e7;
} dp[0] = 0;
for (int i = 0; i < coins.size(); i ++) {
for (int j = coins[i]; j <= amount; j ++) {
dp[j] = min(dp[j], dp[j - coins[i]] + 1);
}
}
return dp[amount] < 1e7 ? dp[amount] : -1;
}
};
32. 最长有效括号
class Solution {
public:
int longestValidParentheses(string s) {
int ans = 0;
stack<int> stk;
stk.push(-1);
for (int i = 0; i < s.length(); i ++) {
if (s[i] == '(') {
stk.push(i);
} else {
stk.pop();
if (!stk.empty()) {
ans = max(i - stk.top(), ans);
} else {
stk.push(i);
}
}
}
return ans;
}
};
105. 从前序与中序遍历序列构造二叉树
class Solution {
public:
TreeNode* createTree(vector<int>& preorder, int x1, int y1, vector<int>& inorder, int x2, int y2) {
if (x1 > y1) return NULL;
else if (x1 == y1) return new TreeNode(preorder[x1]);
TreeNode* ret = new TreeNode(preorder[x1]);
int loc = x2;
while (inorder[loc] != preorder[x1]) {
loc ++;
}
if (loc == x2) {
ret -> left = NULL;
} else {
ret -> left = createTree(preorder, x1 + 1, x1 + loc - x2, inorder, x2, loc - 1);
}
if (loc == y2) {
ret -> right = NULL;
} else {
ret -> right = createTree(preorder, x1 + 1 + loc - x2, y1, inorder, loc + 1, y2);
}
return ret;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder[0] == -1) return new TreeNode(-1);
return createTree(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1);
}
};
155. 最小栈
class MinStack {
private:
stack<pair<int, int>> stk;
public:
MinStack() {
}
void push(int val) {
if (stk.empty()) {
stk.push({val, val});
} else {
stk.push({val, min(val, stk.top().second)});
}
}
void pop() {
stk.pop();
}
int top() {
return stk.top().first;
}
int getMin() {
return stk.top().second;
}
};
43. 字符串相乘
class Solution {
public:
string multiply(string num1, string num2) {
if (num1 == "0" || num2 == "0") return "0";
if (num1 == "1" || num2 == "1") return num1 == "1" ? num2 : num1;
string ans = "";
if (num1.size() < num2.size()) {
string tmp;
tmp = num1;
num1 = num2;
num2 = tmp;
}
reverse(num1.begin(), num1.end()), reverse(num2.begin(), num2.end());
int add = 0, n = num1.size(), m = num2.size();
for (int i = 0; i < n + m - 1; i ++) {
for (int j = 0; j < m; j ++) {
if (i >= j && i < j + n) {
add += (num2[j] - '0') * (num1[i - j] - '0');
}
}
ans.insert(ans.begin(), add % 10 + '0');
add /= 10;
}
while (add != 0) {
ans.insert(ans.begin(), add % 10 + '0');
add /= 10;
}
return ans;
}
};
151. 翻转字符串里的单词
class Solution:
def reverseWords(self, s: str) -> str:
s = s.strip()
words = s.split(' ')[::-1]
ans = ""
for w in words:
if len(w.strip()) == 0:
continue
ans += w.strip()
ans += ' '
return ans[:-1]
32. 最长有效括号
class Solution {
public:
int longestValidParentheses(string s) {
int ans = 0;
stack<int> stk;
stk.push(-1);
for (int i = 0; i < s.length(); i ++) {
if (s[i] == '(') {
stk.push(i);
} else {
stk.pop();
if (!stk.empty()) {
ans = max(i - stk.top(), ans);
} else {
stk.push(i);
}
}
}
return ans;
}
};
144. 二叉树的前序遍历
class Solution {
public:
vector<int> ans;
void preTravel(TreeNode* root) {
if (root == NULL) return ;
ans.push_back(root -> val);
if (root -> left != NULL) preTravel(root -> left);
if (root -> right != NULL) preTravel(root -> right);
}
vector<int> preorderTraversal(TreeNode* root) {
preTravel(root);
return ans;
}
};
110. 平衡二叉树
class Solution {
public:
int recur(TreeNode* root) {
if (root == nullptr) return 0;
int left = recur(root->left);
if (left == -1) return -1;
int right = recur(root->right);
if (right == -1) return -1;
return abs(left - right) < 2 ? max(left, right) + 1 : -1;
}
bool isBalanced(TreeNode* root) {
return recur(root) != -1;
}
};
101. 对称二叉树
class Solution {
public:
vector<vector<int>> travel;
void layerTravel(TreeNode* root, int maxDepth, int level) {
if (travel.size() < level) {
if (root == NULL) travel.push_back({-200});
else travel.push_back({root -> val});
} else {
if (root == NULL) travel[level - 1].push_back({-200});
else travel[level - 1].push_back(root -> val);
}
if (level <= maxDepth) {
if (root == NULL) layerTravel(NULL, maxDepth, level + 1);
else if (root -> left == NULL) layerTravel(NULL, maxDepth, level + 1);
else layerTravel(root -> left, maxDepth, level + 1);
}
if (level <= maxDepth) {
if (root == NULL) layerTravel(NULL, maxDepth, level + 1);
else if (root -> right == NULL) layerTravel(NULL, maxDepth, level + 1);
else layerTravel(root -> right, maxDepth, level + 1);
}
}
int getDepth(TreeNode* root) {
if (root == NULL) return 0;
else if (root -> left == NULL && root -> right == NULL) return 1;
return max(getDepth(root -> left), getDepth(root -> right)) + 1;
}
bool isSymmetric(TreeNode* root) {
int depth = getDepth(root);
layerTravel(root, depth, 1);
for (int i = 0; i < travel.size(); i ++) {
if (travel[i].size() % 2 == 1 && i != 0) return false;
for (int j = 0; j < travel[i].size() / 2; j ++) {
if (travel[i][j] != travel[i][travel[i].size() - 1 - j]) return false;
}
}
return true;
}
};
104. 二叉树的最大深度
class Solution {
public:
int dfs(TreeNode* root) {
if (root == NULL) return 0;
else if (root -> left == NULL && root -> right == NULL) return 1;
else if (root -> left == NULL) return dfs(root -> right) + 1;
else if (root -> right == NULL) return dfs(root -> left) + 1;
else return max(dfs(root -> left), dfs(root -> right)) + 1;
}
int maxDepth(TreeNode* root) {
return dfs(root);
}
};
129. 求根到叶子节点数字之和
class Solution {
public:
int ans = 0;
void travel(TreeNode* root, int pre) {
if (root == NULL) return ;
if (root -> left == NULL && root -> right == NULL) {
ans += pre * 10 + root -> val;
} else if (root -> left == NULL) {
travel(root -> right, pre * 10 + root -> val);
} else if (root -> right == NULL) {
travel(root -> left, pre * 10 + root -> val);
} else {
travel(root -> left, pre * 10 + root -> val);
travel(root -> right, pre * 10 + root -> val);
}
}
int sumNumbers(TreeNode* root) {
travel(root, 0);
return ans;
}
};
543. 二叉树的直径
class Solution {
public:
int ans = 0;
int dfs(TreeNode* root) {
if (root == NULL) return -1;
else if (root -> left == NULL && root -> right == NULL) return 0;
int left, right;
left = dfs(root -> left);
right = dfs(root -> right);
ans = max(ans, left + right + 2);
return max(left, right) + 1;
}
int diameterOfBinaryTree(TreeNode* root) {
int tmp;
tmp = dfs(root);
ans = max(tmp, ans);
return ans;
}
};
98. 验证二叉搜索树
class Solution {
public:
vector<int> t;
void midTravel(TreeNode* root) {
if (root == NULL) return ;
else if (root -> left == NULL && root -> right == NULL) {
t.push_back(root -> val);
return ;
}
if (root -> left != NULL) midTravel(root -> left);
t.push_back(root -> val);
if (root -> right != NULL) midTravel(root -> right);
}
bool isValidBST(TreeNode* root) {
midTravel(root);
for (int i = 1; i < t.size(); i ++) {
if (t[i] <= t[i - 1]) {
return false;
}
}
return true;
}
};
113. 路径总和 II
470. 用 Rand7() 实现 Rand100()
64. 最小路径和
39. 组合总和
48. 旋转图像
394. 字符串解码
234. 回文链表
112. 路径总和
34. 在排序数组中查找元素的最后一个位置
221. 最大正方形
240. 搜索二维矩阵 II
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int i = 0, j = matrix[0].size() - 1;
while(i >= 0 && i < matrix.size() && j >= 0 & j < matrix[0].size()) {
if (matrix[i][j] == target) return true;
else if (matrix[i][j] < target) i++;
else j --;
}
return false;
}
};