题解31-36

79. 单词搜索 - 力扣(LeetCode)

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例 1:
在这里插入图片描述

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true

示例 2:

在这里插入图片描述

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true

示例 3:
在这里插入图片描述

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false

提示:

  • m == board.length
  • n = board[i].length
  • 1 <= m, n <= 6
  • 1 <= word.length <= 15
  • boardword 仅由大小写英文字母组成

**进阶:**你可以使用搜索剪枝的技术来优化解决方案,使其在 board 更大的情况下可以更快解决问题?

思路:

经典dfs思路,注意这个是全局搜索,所以不要忘记每次改变了字符串时候需要改回去

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        for(int i = 0; i < board.size(); i ++)
        {
            for(int j = 0; j < board[i].size(); j ++)
            {
                if(dfs(board, word, 0, i, j))
                    return true;
            }
        }
        return false;
    }
    bool dfs(vector<vector<char>> &board, string &str, int u, int x, int y) {
        if (board[x][y] != str[u]) return false;
        if (u == str.size() - 1) return true;
        int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
        char t = board[x][y];
        board[x][y] = '*';
        for (int i = 0; i < 4; i ++ ) {
            int a = x + dx[i], b = y + dy[i];
            if (a >= 0 && a < board.size() && b >= 0 && b < board[a].size()) {
                if (dfs(board, str, u + 1, a, b)) return true;
            }
        }
        board[x][y] = t;
        return false;
    }


    
};

84. 柱状图中最大的矩形 - 力扣(LeetCode)

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:
在这里插入图片描述

输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10

示例 2:

输入: heights = [2,4]
输出: 4

提示:

  • 1 <= heights.length <=105
  • 0 <= heights[i] <= 104
思路:

此题的本质是找到每个柱形条左侧第一个比自己低或相等,以及右侧第一个严格比自己低的矩形条,然后用宽度乘上当前柱形条的高度作为备选答案。
解决此类问题的经典做法是单调栈,维护一个单调递增的栈,如果当前柱形条 i 的高度比栈顶要低,则栈顶元素 cur 出栈。出栈后,cur 右侧第一个严格比自己低的柱形条就是 i,左侧第一个比自己低或相等的柱形条是当前栈中的 top。不断出栈直到栈为空或者柱形条 i 不再比 top 低。
满足 2 之后,当前矩形条 i 进栈。

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        heights.push_back(-1);
        int n = heights.size();
        stack<int> st;
        
        int ans = 0;
        for(int i = 0; i <= n; i ++)
        {
            while(st.size() && heights[i] < heights[st.top()])
            {
                int cur = st.top();
                st.pop();
                if(st.empty())
                    ans = max(ans, heights[cur] * i);
                else
                    ans = max(ans, heights[cur] * (i - st.top() - 1));
            }
            st.push(i);
        }
        return ans;
    }
};

85. 最大矩形 - 力扣(LeetCode)

给定一个仅包含 01 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例 1:
在这里插入图片描述

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示。

示例 2:

输入:matrix = [["0"]]
输出:0

示例 3:

输入:matrix = [["1"]]
输出:1

提示:

  • rows == matrix.length
  • cols == matrix[0].length
  • 1 <= row, cols <= 200
  • matrix[i][j]'0''1'
思路:

这道题可以看作是二维的矩形,我们可以把矩形竖起来有多少个就看成值由多少,然后复用84题的单调栈就行了

class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        int n = matrix.size(), m, ans = 0;
        if (n == 0)
            return 0;

        m = matrix[0].size();
        vector<int> heights(m + 1, 0);
        heights[m] = -1;

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++)
                if (matrix[i][j] == '0')
                    heights[j] = 0;
                else
                    heights[j]++;
            
            stack<int> st;
            for (int j = 0; j <= m; j++) {
                while (!st.empty() && heights[j] < heights[st.top()]) {
                    int cur = st.top();
                    st.pop();

                    if (st.empty())
                        ans = max(ans, heights[cur] * j);
                    else
                        ans = max(ans, heights[cur] * (j - st.top() - 1));
                }

                st.push(j);
            }
        }

        return ans;
    }
};

94. 二叉树的中序遍历 - 力扣(LeetCode)

给定一个二叉树的根节点 root ,返回 它的 中序 遍历

示例 1:
在这里插入图片描述

输入:root = [1,null,2,3]
输出:[1,3,2]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

提示:

  • 树中节点数目在范围 [0, 100]
  • -100 <= Node.val <= 100
思路:

这道题先完成了递归写法,迭代写法todo

/**
 * 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:
    void dfs(TreeNode* cur, vector<int>& res)
    {
        if(cur == nullptr)  return ;
        dfs(cur->left, res);
        res.push_back(cur->val);
        dfs(cur->right, res);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        if(root == nullptr) return res;
        dfs(root, res);
        return res;
    }
};

96. 不同的二叉搜索树 - 力扣(LeetCode)

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。

示例 1:
在这里插入图片描述

输入:n = 3
输出:5

示例 2:

输入:n = 1
输出:1

提示:

  • 1 <= n <= 19
思路:

这道题就是卡特兰数

class Solution {
public:
    int numTrees(int n) {
        vector<int> f(n + 1);
        f[0] = 1;
        for(int i = 1; i <= n; i ++)
            for(int j = 1; j <= i; j ++)
                f[i] += f[j - 1]* f[i - j];
        return f[n];

    }
};

98. 验证二叉搜索树 - 力扣(LeetCode)

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:
在这里插入图片描述

输入:root = [2,1,3]
输出:true

示例 2:
在这里插入图片描述

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

提示:

  • 树中节点数目范围在[1, 104]
  • -231 <= Node.val <= 231 - 1
思路:

这道题可以采用先序中序后序来实现,这里先完成先序的写法,通过传入当前节点的值往下来判断是否是一个合理的二叉树

/**
 * 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:
    bool isValidBST(TreeNode* root, long left = LONG_MIN, long right = LONG_MAX) {
        if(root == nullptr)
            return true;
        long x = root->val;
        return left < x && x < right && isValidBST(root->left, left, x) && isValidBST(root->right, x, right);
    }
};
  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值