Analysis of Leetcode Problem Solving Ideas (31) 221-227

  1. Largest Square
    In a two-dimensional matrix consisting of 0 and 1, find the largest square that contains only 1 and return its area.

Understanding the state transition equation can simply solve 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. Complete Binary Tree
    Given a complete binary tree, find the number of nodes in the tree.

The simplest method is to traverse all nodes and accumulate. In addition, you can only count the last layer: if the depth of the left and right subtrees is equal, the left is a full binary tree, and the right is more than the left and the right must be a full binary tree.

/**
 * 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. Rectangular Area
    Calculate the total area formed by overlapping two rectangles formed by straight lines on a two-dimensional plane.

A very boring question, meaningless

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. Basic calculator
    Implement a basic calculator to calculate the value of a simple string expression.
    String expressions can include left parenthesis (, right parenthesis), plus sign +, minus sign -, non-negative integers and spaces.

The idea of ​​this question is to use the stack to save the parentheses, and the left parenthesis into the stack and the right parenthesis out of the stack. The optimization point is that we can only use addition: subtraction is treated as a negative number, which can avoid the string reverse rearrangement

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. Implement stack with queue

There are two ways to implement the first-in-last-out queue of the stack: use auxiliary queues, or take out all the previous ones and put them behind each time they are put on the stack.

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. Flip Binary Tree
    Flip a binary tree.

This problem can be solved by recursion, similar to depth first, or iterative, similar to breadth first

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. Basic calculator 2
    implements a basic calculator to calculate the value of a simple string expression.
    String expressions only contain non-negative integers, +, -, *, / four operators and spaces. Integer division only retains the integer part.
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;
    }
};

Guess you like

Origin blog.csdn.net/u013354486/article/details/106951185