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
board
和word
仅由大小写英文字母组成
**进阶:**你可以使用搜索剪枝的技术来优化解决方案,使其在 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)
给定一个仅包含 0
和 1
、大小为 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
个节点组成且节点值从 1
到 n
互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例 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);
}
};