695
/*
* 给你一个大小为 m x n 的二进制矩阵 grid 。
岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。
岛屿的面积是岛上值为 1 的单元格的数目。
计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。
思路:
1.先判断是否超出边界,若超出边界就直接返回0,否则检查该方块是否是陆地,若是陆地,就将该陆地标记为水面,返回时加1
2.对每个节点进行遍历(两层for循环)
*/
class Solution {
private:
int Max = 0;
int dfs(int i, int j, vector <vector<int>> &grid) {
if (i < 0 || i >= grid.size() || j < 0 || j >= grid[0].size() || grid[i][j] == 0)return 0;
grid[i][j] = 0;
return 1 + dfs(i - 1, j, grid)
+ dfs(i + 1, j, grid)
+ dfs(i, j - 1, grid)
+ dfs(i, j + 1, grid);
}
public:
int maxAreaOfIsland(vector <vector<int>> &grid) {
// vector <vector<int>> vis(grid.size(), vector<int>(grid[0].size()));
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == 1)
Max = max(dfs(i, j, grid), Max);
}
}
return Max;
}
};
812 每日一题,简单题?
/*给定包含多个点的集合,从其中取三个点组成三角形,返回能组成的最大三角形的面积。
*
* */
class Solution {
private:
int cross(const vector<int> & p, const vector<int> & q, const vector<int> & r) {
return (q[0] - p[0]) * (r[1] - q[1]) - (q[1] - p[1]) * (r[0] - q[0]);
}
vector<vector<int>> getConvexHull(vector<vector<int>>& points) {
int n = points.size();
if (n < 4) {
return points;
}
/* 按照 x 大小进行排序,如果 x 相同,则按照 y 的大小进行排序 */
sort(points.begin(), points.end(), [](const vector<int> & a, const vector<int> & b) {
if (a[0] == b[0]) {
return a[1] < b[1];
}
return a[0] < b[0];
});
vector<vector<int>> hull;
/* 求出凸包的下半部分 */
for (int i = 0; i < n; i++) {
while (hull.size() > 1 && cross(hull[hull.size() - 2], hull.back(), points[i]) <= 0) {
hull.pop_back();
}
hull.emplace_back(points[i]);
}
int m = hull.size();
/* 求出凸包的上半部分 */
for (int i = n - 2; i >= 0; i--) {
while (hull.size() > m && cross(hull[hull.size() - 2], hull.back(), points[i]) <= 0) {
hull.pop_back();
}
hull.emplace_back(points[i]);
}
/* hull[0] 同时参与凸包的上半部分检测,因此需去掉重复的 hull[0] */
hull.pop_back();
return hull;
}
double triangleArea(int x1, int y1, int x2, int y2, int x3, int y3) {
return 0.5 * abs(x1 * y2 + x2 * y3 + x3 * y1 - x1 * y3 - x2 * y1 - x3 * y2);
}
public:
double largestTriangleArea(vector<vector<int>> & points) {
auto convexHull = getConvexHull(points);
int n = convexHull.size();
double ret = 0.0;
for (int i = 0; i < n; i++) {
for (int j = i + 1, k = i + 2; j + 1 < n; j++) {
while (k + 1 < n) {
double curArea = triangleArea(convexHull[i][0], convexHull[i][1], convexHull[j][0], convexHull[j][1], convexHull[k][0], convexHull[k][1]);
double nextArea = triangleArea(convexHull[i][0], convexHull[i][1], convexHull[j][0], convexHull[j][1], convexHull[k + 1][0], convexHull[k + 1][1]);
if (curArea >= nextArea) {
break;
}
k++;
}
double area = triangleArea(convexHull[i][0], convexHull[i][1], convexHull[j][0], convexHull[j][1], convexHull[k][0], convexHull[k][1]);
ret = max(ret, area);
}
}
return ret;
}
};
offer13
/*
* 地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
*
* */
class Solution {
private:
//计算数字个数之和
int digi_sum(int A) {
int sum = 0;
while (A > 0) {
sum += A % 10;
A /= 10;
}
return sum;
}
//利用二维数组保存访问数据
int dfs(int i, int j, int n, int m, int k, vector <vector<bool>> &vis) {
//若出界(i<0||j<0||i>=m||j>=n),或者是数位和大于K(digi_sum(i)+digi_sum(j))>k或者是访问过vis[i][j]==true,就返回0
if (i < 0 || j < 0 || i >= m || j >= n || (digi_sum(i) + digi_sum(j)) > k || vis[i][j] == true)return 0;
//没访问过(i,j)就标记vis[i][j]==true
vis[i][j] = true;
//因为新增加访问,就可以在结果上+1,递归的访问上下左右
return 1 + dfs(i - 1, j, n, m, k, vis)
+ dfs(i + 1, j, n, m, k, vis)
+ dfs(i, j - 1, n, m, k, vis)
+ dfs(i, j + 1, n, m, k, vis);
}
public:
int movingCount(int m, int n, int k) {
vector <vector<bool>> vis(m, vector<bool>(n));
//递归从零开始
int ans = dfs(0, 0, n, m, k, vis);
return ans;
}
};
offer26
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
* 输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
例如:
给定的树 A:
3
/ \
4 5
/ \
1 2
给定的树 B:
4
/
1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。
*判断B是否为另一颗树A的子结构
* 思路:最直观的想法就是遍历A树的所有节点,并以该节点为起点与B树进行对比:
* 对比过程:
* 1.若B扫描到的节点为空则说明经过之前的若干次检查(递归),直到找到空节点都不能找到不同的节点,则说明B是A的子结构
* 2.若B不为空,if(rt1==nullptr||rt1->val!=rt2->val),则若A为空则说明肯定不是子结构
*
*
* */
class Solution {
private:
bool find(TreeNode *rt1, TreeNode *rt2) {
if (rt2 == nullptr)return true;
if (rt1 == nullptr || rt1->val != rt2->val)return false;
return find(rt1->left, rt1->left) && find(rt1->right, rt2->right);
}
public:
bool isSubStructure(TreeNode *A, TreeNode *B) {
return (A != nullptr && B != nullptr) &&
(find(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B));
//先进行非空检查,再进行以两树根节点为起点的检查,再递归地以A树子节点和B树根节点为参数的检查
}
};