leetcode-------N-Queen

N-Queens 问题,就是找出不同的N-Queens,我刚开始以为只是以为只要把第一行的Q放不同的位置,后面可能就固定了,于是思考的种类就少了,这其实在学栈的时候,就学过,思想就是,在栈里放入之前Q的位置,分别检查下一个要放入的位置是否和栈里所有的Q冲突,如果没有,则入栈,否则下一个,直到N-Queens放满为止, 

下面的解法,只考虑了第一行的Q的不同位置,(后期有改进)

class Solution {
public:
	bool check(stack<pair<int, int>> &sta, int cur_row, int cur_col)
	{
		stack<pair<int, int>> copy = sta;
		while (!copy.empty())
		{
			auto cur = copy.top();
			copy.pop();
			if (cur.first == cur_row ||
				cur.second == cur_col ||
				(cur.second - cur.first) == (cur_col - cur_row ) ||
				(cur.second + cur.first) == (cur_row + cur_col))
			{
				return false;
			}

		}
		return true;
	}
	void push_dot(vector<string> &res, int row, int col)
	{
		for (int i = col; i < res.size(); ++i)
		{
			char var = '.';
			res[row][col]= var;
		}
	}
	vector<vector<string>> solveNQueens(int n) {
		vector<vector<string>> solu;
		int j = 0;
		while(j<n)
		{
			int row = 0;
			int col = 0;
			int queen = 1;
			stack<pair<int, int>> record;
            string _module;
            for(int i=0;i<n;++i)
            {
                _module+=".";
            }
			vector<string> res(n, _module);
			char var = 'Q';
			res[0][j] = var;
			record.push(pair<int, int>(0, j));
			push_dot(res, 0, j + 1);
			col = 0;
			row = 1;
			while (row < n  && col < n  && queen <= n)
			{
				if (check(record, row, col)) {
					record.push(pair<int, int>(row, col));
					var = 'Q';
					res[row][col] = var;
					push_dot(res, row, col + 1);
					col = 0;
					row++;
					queen++;
				}
				else {
					if (col < n - 1) {
						var = '.';
						res[row][col++] = var;
					}
					else {
						auto last = record.top();
						row = last.first;
						col = last.second;
						var = '.';
						res[row][col] = var;
						queen--;
						record.pop();
						if (col < n - 1)	col++;
						else {
							if (record.empty())	break;
							row = record.top().first;
							col = record.top().second;
							var = '.';
							res[row][col] = var;
							col++;
							queen--;
							record.pop();
						}

					}

				}
			}
			if (record.empty())	break;
			while (record.size()>1)
			{
				record.pop();
			}
			auto  a = record.top();
			j =  a.second+ 1;
			solu.push_back(res);
		}
		return solu;
	}
};

要考虑所有种情况,于是我就考虑了回溯法,让系统帮我压栈,的确会变慢很多 ,可能要让空间复杂度变低,则需要改成迭代法

class S1olution {
public:
	bool check(stack<pair<int, int>> &sta, int cur_row, int cur_col)
	{
		stack<pair<int, int>> copy = sta;
		while (!copy.empty())
		{
			auto cur = copy.top();
			copy.pop();
			if (cur.first == cur_row ||
				cur.second == cur_col ||
				(cur.second - cur.first) == (cur_col - cur_row ) ||
				(cur.second + cur.first) == (cur_row + cur_col))
			{
				return false;
			}

		}
		return true;
	}
	void push_dot(vector<string> &res, int row, int col)
	{
		for (int i = col; i < res.size(); ++i)
		{
			char var = '.';
			res[row][col]= var;
		}
	}

	void back_in(vector<vector<string>> &solu,vector<string> &res, int row, int col,stack<pair<int, int>> &record,int &queen)
	{
		int old = queen;
		int n = res.size();
		if (row == n) { 
			solu.push_back(res);
			return ; 
		}
		if (col == n)	return ;
		if (check(record, row, col)) {
			record.push(pair<int, int>(row, col));
			char var = 'Q';
			res[row][col] = var;
			queen++;
			push_dot(res, row, col + 1);
			back_in(solu, res, row + 1, 0, record, queen);
			//此时下面为回溯
			while (queen > old)
			{
				record.pop();
				queen--;
			}
			var = '.';
			res[row][col] = var;
			back_in(solu, res, row, col + 1, record, queen);
			//above
			
		}
		else { 
			char var = '.';
			res[row][col] = var;
			back_in(solu, res, row, ++col, record, queen);
		}
		
		
	}
	vector<vector<string>> solveNQueens(int n) {
		vector<vector<string>> solu;
		stack<pair<int, int>> record;
		string _module;
		for (int i = 0; i < n; ++i)
		{
			_module += ".";
		}
		int queen = 0;
		vector<string> res(n, _module);
		back_in(solu, res, 0, 0, record,queen);
		return solu;

	}
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值