Análisis de ideas de resolución de problemas de Leetcode (31) 221-227

  1. 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;
    }
};

  1. Á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;
    }
};

  1. Á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;

    }
};


  1. 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;
    }
};


  1. 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;
};


  1. 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;
    }
};

  1. 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;
    }
};

Supongo que te gusta

Origin blog.csdn.net/u013354486/article/details/106951185
Recomendado
Clasificación