- Cuadrado más grande
En una matriz bidimensional compuesta por 0 y 1, encuentre el cuadrado más grande que contenga solo 1 y devuelva su área.
Entender la ecuación de transición de estado simplemente puede resolver dp (i, j) = min (dp (i - 1, j), dp (i - 1, j - 1), dp (i, j - 1)) + 1
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.size() == 0 || matrix[0].size() == 0) {
return 0;
}
int maxSide = 0;
int rows = matrix.size(), columns = matrix[0].size();
vector<vector<int>> dp(rows, vector<int>(columns));
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (matrix[i][j] == '1') {
if (i == 0 || j == 0) {
dp[i][j] = 1;
} else {
dp[i][j] = min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
}
maxSide = max(maxSide, dp[i][j]);
}
}
}
int maxSquare = maxSide * maxSide;
return maxSquare;
}
};
- Árbol binario completo
Dado un árbol binario completo, calcule el número de nodos en el árbol.
El método más simple es atravesar todos los nodos y sumarlos. Además, solo puede contar la última capa: si la profundidad de los subárboles izquierdo y derecho es igual, el izquierdo es un árbol binario completo y el derecho es más que el izquierdo y el derecho debe ser un árbol binario completo.
/**
* 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:
int countNodes(TreeNode* root) {
int cnt = 0;
queue<TreeNode *> nodes;
if (root == NULL)
return cnt;
nodes.push(root);
while (nodes.size())
{
TreeNode *curr = nodes.front();
nodes.pop();
cnt++;
if (curr->left)
nodes.push(curr->left);
if (curr->right)
nodes.push(curr->right);
}
return cnt;
}
};
/**
* 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:
int countNodes(TreeNode* root) {
if(!root)
return 0;
int left = depth(root->left);
int right = depth(root->right);
if(left==right){
return pow(2,left)+countNodes(root->right);
}
else{
return pow(2,right)+countNodes(root->left);
}
}
int depth(TreeNode* root){
int ans = 0;
while(root){
ans++;
root = root->left;
}
return ans;
}
};
- Área rectangular
Calcula el área total formada por la superposición de dos rectángulos formados por líneas rectas en un plano bidimensional.
Una pregunta muy aburrida, sin sentido
class Solution {
public:
int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
//先判定不重叠的情况,不重叠的话,就是两者面积相加
if((C <= E || G <= A || D <= F || H <= B)){
return (C - A) * (D - B) + (G - E) * (H - F);
};
//用向量的思想来算:
//计算一共分四种情况:[A,E,C,G], [E,A,G,C], [A,E,G,C], [E,A,C,G]。
//所以,可以得到的是:dx = 两边长 - 最大的长;
//算两条边的边长
int whole_x = (C - A) + (G - E);
int whole_y = (D - B) + (H - F);
//算最大的长
int x[4] = {
A,C,E,G};
int y[4] = {
B,D,F,H};
//排序选最大和最小值
sort(x,x+4);
sort(y,y+4);
//最长边
int large_x = x[3] - x[0];
int large_y = y[3] - y[0];
//重叠区域面积
int delta_area = (whole_x - large_x) * (whole_y - large_y);
//两个矩形面积
int area_a = (C - A) * (D - B);
int area_b = (G - E) * (H - F);
//这里容易越界
return area_b - delta_area + area_a;
}
};
- Calculadora básica
Implemente una calculadora básica para calcular el valor de una expresión de cadena simple.
Las expresiones de cadena pueden incluir paréntesis izquierdo (, paréntesis derecho), signo más +, signo menos -, enteros no negativos y espacios.
La idea de esta pregunta es usar la pila para guardar los paréntesis, y el paréntesis izquierdo en la pila y el paréntesis derecho fuera de la pila. El punto de optimización es que solo podemos usar la suma: la resta se trata como un número negativo, lo que puede evitar el reordenamiento inverso de la cadena
class Solution {
public:
int calculate(string s) {
stack<int> st;
int res = 0, n = s.size(), sign = 1;
for(int i=0; i<n; i++) {
int num = 0;
if(s[i] >= '0') {
while(i<n && s[i] >= '0') {
num = num * 10 + (s[i] - '0');
i++;
}
i--;
res += sign * num;
}
else if(s[i] == '+') sign = 1;
else if(s[i] == '-') sign = -1;
else if(s[i] == '(') {
st.push(res);
st.push(sign);
res = 0;
sign = 1;
}
else if(s[i] == ')') {
res *= st.top(); st.pop();
res += st.top(); st.pop();
}
}
return res;
}
};
- Implementar pila con cola
Hay dos formas de implementar la cola del primero en entrar, el último en salir de la pila: usar colas auxiliares o sacar todas las anteriores y ponerlas detrás cada vez que se colocan en la pila.
class MyStack {
public:
/** Initialize your data structure here. */
MyStack() = default;
/** Push element x onto stack. */
void push(int x) {
que.push(x);
for (int i = 0; i + 1 < que.size(); i++) {
que.push(que.front());
que.pop();
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int val = top();
que.pop();
return val;
}
/** Get the top element. */
int top() {
return que.front();
}
/** Returns whether the stack is empty. */
bool empty() {
return que.empty();
}
private:
queue<int> que;
};
- Voltear árbol binario
Voltea un árbol binario.
Este problema se puede resolver mediante recursividad, similar a la profundidad primero, o iterativo, similar a la amplitud primero
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(!root) return nullptr;
swap(root->left, root->right);
root->left = invertTree(root->left);
root->right = invertTree(root->right);
return root;
}
};
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> stk;
if(root) stk.push(root);
while(stk.size()) {
TreeNode* tr = stk.top();
stk.pop();
swap(tr->left, tr->right);
if(tr->left) stk.push(tr->left);
if(tr->right) stk.push(tr->right);
}
return root;
}
};
- La calculadora básica 2
implementa una calculadora básica para calcular el valor de una expresión de cadena simple.
Las expresiones de cadena solo contienen números enteros no negativos, +, -, *, / cuatro operadores y espacios. La división entera solo conserva la parte entera.
class Solution {
public:
int calculate(string s) {
int begin = 0;
return calHelper(s, begin);
}
int calHelper(string s, int& i) //i用于记录计算开始的索引
{
char operation = '+';
stack<int> nums;
int num = 0;
int res = 0;
bool flag = false;
for (i; i < s.size(); i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
num = num * 10 + (s[i] - '0');
}
if (s[i] == '(')
{
num = calHelper(s, ++ i); //从i的下一个开始计算, 进入递归
i++; //计算完之后的i指向)所以再++
}
if (((s[i] < '0' || s[i] > '9') && s[i] != ' ') || i >= s.size() - 1) // 继续计算
{
int pre = 0;
switch (operation)
{
case '+': nums.push(num);
break;
case '-': nums.push(-num);
break;
case '*':
pre = nums.top();
nums.pop();
nums.push(pre * num);
break;
case '/':
pre = nums.top();
nums.pop();
nums.push(pre / num);
break;
}
operation = s[i];
num = 0;
}
if (s[i] == ')') //遇到)回到上一级递归
{
break;
}
}
while (!nums.empty())
{
res += nums.top();
nums.pop();
}
return res;
}
};