10.13(129. 求根到葉子節點數字之和 130. 被圍繞的區域)

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);
			}
		}
	}
};

其實標準答案的思路和我的思路二的思路是幾乎一樣的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章