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);
}
}
}
};
其實標準答案的思路和我的思路二的思路是幾乎一樣的。