/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
rserialize(root);
return ans;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
string str;
for (char ch : data) {
if (ch == ',') {
dataArray.push_back(str);
str = "";
}
else
str += ch;
}
return rdeserialize();
}
private:
string ans;
list<string> dataArray;
void rserialize(TreeNode* root) {
if (root == nullptr) {
ans += "null,";
return;
}
ans += to_string(root->val) + ",";
rserialize(root->left);
rserialize(root->right);
}
TreeNode* rdeserialize() {
if (dataArray.front() == "null") {
dataArray.erase(dataArray.begin());
return nullptr;
}
TreeNode* root = new TreeNode(stoi(dataArray.front()));
dataArray.erase(dataArray.begin());
root->left = rdeserialize();
root->right = rdeserialize();
return root;
}
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));
class Solution {
public:
int minMutation(string startGene, string endGene, vector<string>& bank) {
unordered_set<string> hashBank;
for (string& seq : bank) hashBank.insert(seq);
if (hashBank.find(endGene) == hashBank.end()) return -1;
const char gene[4] = {'A', 'C', 'G', 'T'};
unordered_map<string, int> depth;
depth[startGene] = 0;
queue<string> q;
q.push(startGene);
while (!q.empty()) {
string s = q.front();
q.pop();
for (int i = 0; i < 8; i++)
for (int j = 0; j < 4; j++)
if (s[i] != gene[j]) {
string ns = s;
ns[i] = gene[j];
if (hashBank.find(ns) == hashBank.end()) continue;
if (depth.find(ns) != depth.end()) continue;
depth[ns] = depth[s] + 1;
q.push(ns);
if (ns == endGene) return depth[ns];
}
}
return -1;
}
};
-
329. 矩阵中的最长递增路径 - 力扣(LeetCode)
法一:拓扑序+BFS
class Solution {
public:
int longestIncreasingPath(vector<vector<int>>& matrix) {
m = matrix.size();
n = matrix[0].size();
to = vector<vector<int>>(m * n);
degree = vector<int>(m * n);
depth = vector<int>(m * n);
const int dx[4] = {-1, 0, 0, 1};
const int dy[4] = {0, -1, 1, 0};
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < 4; k++) {
int ni = i + dx[k];
int nj = j + dy[k];
if (valid(ni, nj) && matrix[ni][nj] > matrix[i][j])
addEdge(num(i, j), num(ni, nj));
}
queue<int> q;
for (int i = 0; i < m * n; i++)
if (degree[i] == 0) {
q.push(i);
depth[i] = 1;
}
while (!q.empty()) {
int x = q.front();
q.pop();
for (int y : to[x]) {
degree[y]--;
depth[y] = max(depth[y], depth[x] + 1);
if (degree[y] == 0) q.push(y);
}
}
int ans = 0;
for (int i = 0; i < m * n; i++) ans = max(ans, depth[i]);
return ans;
}
private:
vector<vector<int>> to;
vector<int> degree;
vector<int> depth;
int m, n;
void addEdge(int x, int y) {
to[x].push_back(y);
degree[y]++;
}
bool valid(int i, int j) {
return i >= 0 && i < m && j >= 0 && j < n;
}
int num(int i, int j) {
return i * n + j;
}
};
法二:DFS+记忆化
class Solution {
public:
int longestIncreasingPath(vector<vector<int>>& matrix) {
m = matrix.size();
n = matrix[0].size();
this->matrix = matrix;
dist = vector<vector<int>>(m, vector<int>(n));
int ans = 0;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
ans = max(ans, dfs(i, j));
return ans;
}
private:
const int dx[4] = {-1, 0, 0, 1};
const int dy[4] = {0, -1, 1, 0};
vector<vector<int>> dist;
vector<vector<int>> matrix;
int m, n;
bool valid(int i, int j) {
return i >= 0 && i < m && j >= 0 && j < n;
}
int dfs(int sx, int sy) {
if (dist[sx][sy] != 0) return dist[sx][sy];
dist[sx][sy] = 1;
for (int i = 0; i < 4; i++) {
int nx = sx + dx[i];
int ny = sy + dy[i];
if (valid(nx, ny) && matrix[nx][ny] > matrix[sx][sy])
dist[sx][sy] = max(dist[sx][sy], dfs(nx, ny) + 1);
}
return dist[sx][sy];
}
};
-
23. 合并 K 个升序链表 - 力扣(LeetCode)
法一:优先队列
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
for (ListNode* node : lists) {
if (node == nullptr) continue;
q.push({node->val, node});
}
ListNode head;
ListNode* tail = &head;
while (!q.empty()) {
Node node = q.top();
q.pop();
tail->next = node.listNode;
tail = tail->next;
ListNode* next = node.listNode->next;
if (next != nullptr)
q.push({next->val, next});
}
return head.next;
}
private:
struct Node {
int key;
ListNode* listNode;
bool operator <(const Node& r) const {
return key > r.key;
}
};
priority_queue<Node> q;
};
法二:二叉堆
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
struct Node {
int key;
ListNode* listNode;
};
class BinaryHeap {
public:
BinaryHeap() {
heap.push_back({0, nullptr});
}
bool empty() {
return heap.size() == 1;
}
Node getMin() {
return heap[1];
}
void insert(Node node) {
heap.push_back(node);
heapifyUp(heap.size() - 1);
}
void removeMin() {
heap[1] = heap[heap.size() - 1];
heap.pop_back();
heapifyDown(1);
}
private:
vector<Node> heap;
void heapifyUp(int p) {
while (p > 1) {
int fa = p / 2;
if (heap[fa].key > heap[p].key) {
swap(heap[fa], heap[p]);
p = fa;
}
else break;
}
}
void heapifyDown(int p) {
int child = p * 2;
while (child < heap.size()) {
int other = p * 2 + 1;
if (other < heap.size() && heap[other].key < heap[child].key)
child = other;
if (heap[p].key > heap[child].key) {
swap(heap[p], heap[child]);
p = child;
child = p * 2;
}
else break;
}
}
};
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
BinaryHeap q;
for (ListNode* node : lists) {
if (node == nullptr) continue;
q.insert({node->val, node});
}
ListNode head;
ListNode* tail = &head;
while (!q.empty()) {
Node node = q.getMin();
q.removeMin();
tail->next = node.listNode;
tail = tail->next;
ListNode* next = node.listNode->next;
if (next != nullptr)
q.insert({next->val, next});
}
return head.next;
}
};
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
// <val, idx>
priority_queue<pair<int, int>> q;
vector<int> ans;
for (int i = 0; i < nums.size(); i++) {
q.push({nums[i], i});
if (i >= k - 1) {
while (q.top().second <= i - k) q.pop();
ans.push_back(q.top().first);
}
}
return ans;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (root == nullptr)
return new TreeNode(val);
if (val < root->val)
root->left = insertIntoBST(root->left, val);
else
root->right = insertIntoBST(root->right, val);
return root;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
TreeNode* ans = nullptr;
TreeNode* cur = root;
while (cur != nullptr) {
if (cur->val == p->val) {
if (p->right != nullptr) {
ans = p->right;
while (ans->left != nullptr) ans = ans->left;
}
break; // 因为如果p没有右孩子,则其后继一定在走过的节点中,所以此时一定已经有结果了,直接退出循环
}
else if (cur->val > p->val) {
// 此处为大于p的最小值
if (ans == nullptr || ans->val > cur->val)
ans = cur;
cur = cur->left;
}
else
cur = cur->right;
}
return ans;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (root == nullptr) return nullptr;
if (root->val == key) {
if (root->left == nullptr) return root->right;
if (root->right == nullptr) return root->left;
TreeNode* next = root->right;
while (next->left != nullptr) next = next->left;
root->val = next->val;
root->right = deleteNode(root->right, next->val);
}
else if (root->val < key)
root->right = deleteNode(root->right, key);
else
root->left = deleteNode(root->left, key);
return root;
}
};
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == target)
return mid;
else if (nums[mid] > target)
right = mid - 1;
else
left = mid + 1;
}
return -1;
}
};
class Solution {
public:
int findMin(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] <= nums[right])
right = mid;
else
left = mid + 1;
}
return nums[right];
}
};
class Solution {
public:
int findMin(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] < nums[right])
right = mid;
else if (nums[mid] > nums[right])
left = mid + 1;
else
right--;
}
return nums[right];
}
};
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> ans;
// 第一个>=target
int left = 0, right = nums.size();
while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] >= target)
right = mid;
else
left = mid + 1;
}
ans.push_back(right);
// 最后一个<=target
left = -1, right = nums.size() - 1;
while (left < right) {
int mid = (left + right + 1) / 2;
if (nums[mid] <= target)
left = mid;
else
right = mid - 1;
}
ans.push_back(right);
if (ans[0] > ans[1]) return {-1, -1};
return ans;
}
};
class Solution {
public:
int mySqrt(int x) {
// 找最大target使得,target*target<=x
int left = 0, right = x;
while (left < right) {
int mid = left + 1 + (right -left - 1) / 2; // 防止越界
if (mid <= x / mid)
left = mid;
else
right = mid - 1;
}
return right;
}
};
// (2 * left - left + right - 1 + 2) / 2 = left + 1 + (right -left - 1) / 2
class Solution {
public:
int findPeakElement(vector<int>& nums) {
// 三分查找
int left = 0, right = nums.size() - 1;
while (left < right) {
int lmid = (left + right) / 2;
int rmid = lmid + 1;
if (nums[lmid] >= nums[rmid])
right = rmid - 1;
else
left = lmid + 1;
}
return right;
}
};
class Solution {
public:
int splitArray(vector<int>& nums, int k) {
// 求解:最小化“m个子数组各自和的最大值”
// 判定:给一个数值T,“m个子数组各自和的最大值<=T”是否合法
// 换一种说法:能否将nums分成m个连续子数组,每组和<=T
int left = 0, right = 0;
for (int num : nums) {
left = max(left, num);
right += num;
}
while (left < right) {
int mid = (left + right) / 2;
if (valid(nums, k, mid))
right = mid;
else
left = mid + 1;
}
return right;
}
private:
bool valid(vector<int>& nums, int k, int size) {
int box = 0;
int cnt = 1;
for (int num : nums) {
if (box + num <= size)
box += num;
else {
box = num;
cnt++;
}
}
return cnt <= k;
}
};
class Solution {
public:
int minDays(vector<int>& bloomDay, int m, int k) {
int latestDay = 0;
for (int day : bloomDay)
latestDay = max(latestDay, day);
int left = 0, right = latestDay + 1;
while (left < right) {
int mid = (left + right) / 2;
if (valid(bloomDay, m, k, mid))
right = mid;
else
left = mid + 1;
}
if (right == latestDay + 1) return -1;
return right;
}
private:
bool valid(vector<int>& bloomDay, int m, int k, int deadLine) {
int seq = 0;
int cnt = 0;
for (int day : bloomDay) {
if (day <= deadLine) {
seq++;
if (seq == k) {
cnt++;
seq = 0;
}
}
else
seq = 0;
}
return cnt >= m;
}
};