版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/musechipin/article/details/82787727
1.设置一个与矩阵同样大小的布尔数组exits,用于表示某一个位置是否已经被访问过。
2.遍历矩阵的每一个位置,如果是标志船的’X’并且该位置没有被访问过,就增加船的数目,然后通过DFS算法把整个船找到,并且把船的所有位置都设为已访问。
3.最后返回找到的船的数目。
我的代码在leetcode上显示数组访问越界,但是在lintcode上过了。不知道哪组测试数据有问题。
class Solution {
public:
int res=0;
int countBattleships(vector<vector<char>>& board) {
if (board.empty()) return 0;
vector<bool> exits(board.size()*board[0].size(), true);
res = 0;
while (FindaShip(board,exits));
return res;
}
bool FindaShip(vector<vector<char>>& board, vector<bool>& exits)
{
int i = 0;
int j = 0;
int m = board.size();
int n = board[0].size();
while (!((board[i][j] == 'X') && (exits[i*n + j] == true)))
{ j++;
if (j == n) { j = 0; i++; }
if (i == m) return false;
}
if ((j + 1<n)&&(board[i][j + 1] == 'X') && (exits[i*n + j + 1] == true))
{
exits[i*n + j] = false;
while ((j+1<n)&& (board[i][j + 1]) == 'X' && (exits[i*n + j + 1] == true))
{ exits[i*n + j + 1] = false;
j++;
}
res++;
}
else if ((i + 1 < m)&&(board[i + 1][j] == 'X') && (exits[(i + 1)*n + j] == true))
{
exits[i*n + j] = false;
while ((i + 1 < m) && (board[i + 1][j] == 'X') && (exits[(i + 1)*n + j] == true))
{ exits[(i + 1)*n + j] = false;
i++;
}
res++;
}
else { res++; exits[i*n + j] = false; }
return true;
}
};
挑战:使用O(1)的存储而且不能改变board上的值。
数船头:这种思路利用了船只能在水平方向或是垂直方向上延伸,因此船的最左边(水平方向)或是最上边(垂直方向)的元素就很特殊,因为它的左边(水平方向)或是上边(垂直方向)的元素会是’.’,而对于船中部的元素,它们的左边或是上边的元素肯定有一个会是’X’。
利用这点,我们可以遍历矩阵每一个元素,当符合是船头元素时,就增加船的个数,否则继续遍历下一个元素,最后返回找到的船的个数即可。
class Solution {
public:
int countBattleships(vector<vector<char>>& board) {
if (board.empty() || board[0].empty()) return 0;
int res = 0, m = board.size(), n = board[0].size();
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (board[i][j] == '.' || (i > 0 && board[i - 1][j] == 'X') || (j > 0 && board[i][j - 1] == 'X')) continue;
++res;
}
}
return res;
}
};