129. 求根到叶子节点数字之和(通过)
思路:递归,前序遍历的应用
效率:100%
程序代码:
/**
* 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:
vector<int> result;
int sumNumbers(TreeNode* root) {
Haha(root,0);//这里是在使用函数
int sum = 0;
for (int e : result) {
sum += e;
}
return sum;
}
void Haha(TreeNode* root,int tmp) {
if (root == NULL) return;
else if (root->left == NULL && root->right == NULL) {
tmp = 10 * tmp + root->val;
result.push_back(tmp);
return;
}
else {
tmp = 10 * tmp + root->val;
Haha(root->left,tmp);
Haha(root->right,tmp);
}
}
};
130. 被围绕的区域(通过)
思路一:
1.扫描二维矩阵,遇到’o’开始执行遍历
2.遍历完成之后如果没有遇到在边界的点flag=0;如果遇到在边界的点flag=1
3.如果flag=0那么重两次遍历,貌似这两遍遍历还没有办法合二为一。
效率:16.42%
比我预想的好了很多了,之前预想按照我编的程序,效率可能连5%都不到。。。。毕竟使用了两边递归,感觉比较冗余
程序代码:
class Solution {
public:
vector<vector<int>> visited;
vector<int> vec;
int flag = 0;//这是一个标志位
void solve(vector<vector<char>>& board) {
int m = board.size();//行
if (m == 0) return;
int n = board[0].size();//列
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
vec.push_back(0);
}
visited.push_back(vec);
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'O'&&visited[i][j] == 0) {
Haha(i, j, m, n, board);//遍历从这个点开始的'0'树,并根据是否符合条件来改变board
flag = 0;//在这里进行初始化
}
}
}
}
void Haha(int i, int j, int m, int n, vector<vector<char>>& board) {
Traverse(i, j, m, n, board);
if (flag == 0) {//更改那一棵树,感觉我这思路好麻烦啊
Change(i, j, m, n, board);
}
}
void Traverse(int i, int j, int m, int n, vector<vector<char>> &board) {
if (i < 0 || i >= m || j < 0 || j >= n)
return;
else {
if (board[i][j] == 'O'&&visited[i][j]==0) {
visited[i][j] = 1;
if (i == 0 || i == m-1 || j == 0 || j == n-1) flag = 1;
Traverse(i + 1, j, m, n, board);
Traverse(i, j + 1, m, n, board);
Traverse(i - 1, j, m, n, board);
Traverse(i, j - 1, m, n, board);
}
}
}
void Change(int i, int j, int m, int n, vector<vector<char>> &board) {
if (i < 0 || i >= m || j < 0 || j >= n) return;
else {
if (board[i][j] == 'O') {
board[i][j] = 'X';
Change(i + 1, j, m, n, board);
Change(i, j + 1, m, n, board);
Change(i - 1, j, m, n, board);
Change(i, j - 1, m, n, board);
}
}
}
};
思路二:
1、只扫描边界点,遇到’o’就开始遍历,遍历之后的点visited=1
2、最后扫描输入的二维向量,如果visited=0并且元素等于’‘o’,就把当前元素的值置为’‘X’。
效率:25.37%,原本以为会比较高来着,还是比较低呀
程序代码:
class Solution {
public:
vector<vector<int>> visited;
vector<int> vec;
void solve(vector<vector<char>>& board) {
int m = board.size();//行
if (m == 0) return;
int n = board[0].size();//列
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
vec.push_back(0);
}
visited.push_back(vec);
}//初始化visited数组
for (int j = 0; j < n; j++) Traverse(0, j, m, n, board);
for (int j = 0; j < n; j++) Traverse(m - 1, j, m, n, board);
for (int i = 0; i < m; i++) Traverse(i, 0, m, n, board);
for (int i = 0; i < m; i++) Traverse(i, n - 1, m, n, board);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'O'&&visited[i][j] == 0)
board[i][j] = 'X';
}
}
}
void Traverse(int i, int j, int m, int n, vector<vector<char>> &board) {
if (i < 0 || i >= m || j < 0 || j >= n)
return;
else {
if (board[i][j] == 'O'&&visited[i][j] == 0) {
visited[i][j] = 1;
Traverse(i + 1, j, m, n, board);
Traverse(i, j + 1, m, n, board);
Traverse(i - 1, j, m, n, board);
Traverse(i, j - 1, m, n, board);
}
}
}
};
优秀答案解析(12ms)
static const auto ban_io_sync = []()
{
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
return 0;
}();
class Solution {
public:
int ops[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
void findNoFill(const vector<vector<char>>& board,vector<vector<bool>>& board_status,int row, int col){
board_status[row][col] = true;
for(int i = 0;i < 4; ++i){
int new_row = row+ops[i][0];
int new_col = col+ ops[i][1];
if( new_row> board.size()-1 || new_col > board[0].size()-1 || new_row <0 || new_col<0 || board_status[new_row][new_col] || board[new_row][new_col] != 'O')
continue;
findNoFill(board,board_status,new_row,new_col);
}
}
void solve(vector<vector<char>>& board) {
if(board.empty() || board[0].empty())
return;
vector<vector<bool>> board_status(board.size(),vector<bool>(board[0].size(),false));
for(int i = 0; i < board[0].size(); ++i){
if(board_status[0][i] || board[0][i] != 'O')
continue;
findNoFill(board,board_status,0,i);
}
if(board.size()>1){
for(int i = 0; i < board[0].size(); ++i){
if(board_status[board.size()-1][i] || board[board.size()-1][i] != 'O')
continue;
findNoFill(board,board_status,board.size()-1,i);
}
}
for(int i = 1; i < board.size()-1; ++i){
if(board_status[i][0]|| board[i][0] != 'O')
continue;
findNoFill(board,board_status,i,0);
}
if(board[0].size()>1){
for(int i = 1; i < board.size()-1; ++i){
if(board_status[i][board[0].size()-1]|| board[i][board[0].size()-1] != 'O')
continue;
findNoFill(board,board_status,i,board[0].size()-1);
}
}
for(int i = 0; i < board.size(); ++i)
for(int j = 0; j < board[0].size(); ++j){
if(!board_status[i][j])
board[i][j]='X';
}
}
};
标准答案很长啊。
参考标准答案之后改进的程序1:
改进的地方:使用一条语句初始化二维向量,而不是使用for循环
vector<vector<int>> visited(board.size(),vector<int>(board[0].size(),1));
程序代码:
class Solution {
public:
//vector<vector<int>> visited;
//ector<int> vec;
void solve(vector<vector<char>>& board) {
int m = board.size();//行
if (m == 0) return;
int n = board[0].size();//列
/*
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
vec.push_back(0);
}
visited.push_back(vec);
}//初始化visited数组
*/
vector<vector<int>> visited(board.size(),vector<int>(board[0].size(),0));
for (int j = 0; j < n; j++) Traverse(0, j, m, n, board,visited);
for (int j = 0; j < n; j++) Traverse(m - 1, j, m, n, board,visited);
for (int i = 0; i < m; i++) Traverse(i, 0, m, n, board,visited);
for (int i = 0; i < m; i++) Traverse(i, n - 1, m, n, board,visited);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'O'&&visited[i][j] == 0)
board[i][j] = 'X';
}
}
}
void Traverse(int i, int j, int m, int n, vector<vector<char>> &board,vector<vector<int>> &visited) {
if (i < 0 || i >= m || j < 0 || j >= n)
return;
else {
if (board[i][j] == 'O'&&visited[i][j] == 0) {
visited[i][j] = 1;
Traverse(i + 1, j, m, n, board,visited);
Traverse(i, j + 1, m, n, board,visited);
Traverse(i - 1, j, m, n, board,visited);
Traverse(i, j - 1, m, n, board,visited);
}
}
}
};
其实标准答案的思路和我的思路二的思路是几乎一样的。