【基础算法】2.回溯算法

回溯算法简介:
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
代表问题:
N皇后问题,全排列问题,解数独问题等;
回溯体模板:

void backtracking(当前标记, 【其他条件1, 其他条件2)
{
	if(当前标记 == 结束条件)
	{
		【如果找到一个结果后就要返回,这里应该设置一个flag= 1】;
		【结束后需要的操作】;
		return}
	else
	{
		for (auto i:遍历范围(数度中遍历范围就是1-9, 全排列中遍历范围就是当前位置到之后的所有元素))
		{
			【在数独,皇后的问题中此步需要判断当前i是否可用】;
			使用i;
			backtrack(标记+1,【其他条件1, 其他条件2)if(flag == 1return ;
			还原i(以便在下一次回溯中继续使用);
		}
	}
	
}

解数独完整代码(为leetcode37题答案):

int flag = 0;    
int usedr[9][10] = {0}, usedc[10][9] = {0};
void init(vector<vector<char>>& board)    
{        
	for (int i = 0; i < 9; i++)        
	{            
		for (int j = 0; j < 9; j++)            
		{                
			if (board[i][j] != '.')                
			{                    
				usedr[i][board[i][j] - '0'] = 1;                    
				usedc[board[i][j] - '0'][j] = 1;                
			}            
		}        
	}    
}    
bool block(int time, vector<vector<char>>& board, int target)    
{        
	int rbegin = time / 9 /3*3;        
	int cbegin = time % 9 /3*3;        
	for (int i = rbegin; i < rbegin + 3; i++)        
	{           
	 	for (int j = cbegin ; j < cbegin + 3; j++)            
	 	{                
	 		if (board[i][j] == target + '0')                    
	 			return false;            
	 	}        
	 }        
	 return true;   
}    
void backtrack(int time, vector<vector<char>>& board)    
{        
	if (time == 81)            
		flag = 1;        
	else        
	{            
		if (board[time/9][time%9] != '.')                
			backtrack(time+1, board);            
		else            
		{                
			for (int i = 1; i < 10; i++)                
			{                    
				if (usedr[time/9][i] == 0 && usedc[i][time%9] == 0 && block(time, board, i))                 	   	
				{                        
					usedr[time/9][i] = 1;                        
					usedc[i][time%9] = 1;                        
					board[time/9][time%9] = i + 48;
                        		
                        		backtrack(time+1, board);                                                		
                        		if (flag == 1)  return ;                        
                        		board[time/9][time%9] = '.';                        
                        		usedr[time/9][i] = 0;                        
                        		usedc[i][time%9] = 0;                    
                        	}                
                        }            
                }        
         }    
}
void solveSudoku(vector<vector<char>>& board)     
{        
	init(board);        
	backtrack(0, board);        
	return ;  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值