10.13(129. 求根到叶子节点数字之和 130. 被围绕的区域)

本文深入探讨了二叉树数字之和求解及矩阵中特定字符的高效遍历策略,提供了两种不同场景下的算法实现,包括递归前序遍历和边界优先搜索方法,对比了不同解决方案的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

其实标准答案的思路和我的思路二的思路是几乎一样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱码仕1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值