LeetCode39/40/22/77/17/401/78/51/46/47/79 11道回溯题(Backtracking)
LeetCode 39
class Solution {
public:
void dfs(int dep, int maxDep, vector<int>& cand, int target)
{
if (target < )return;
if (dep == maxDep)
{
if (target == )//到达尾部且等于target
{
vector<int> temp;
for (int i = ; i < maxDep; i++)
{
for (int j = ; j < num[i]; j++)
temp.push_back(cand[i]);
}
ret.push_back(temp);
}
return;
}
for (int i = ; i <= target / cand[dep]; i++)//枚举合适的情况
{
num[dep] = i;
dfs(dep + , maxDep, cand, target - i*cand[dep]);
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target)
{
int n = candidates.size();
if (n == )return ret;
sort(candidates.begin(), candidates.end());
num.resize(n);
ret.clear();
dfs(, n, candidates, target);
return ret;
}
private:
vector<vector<int>> ret;//返回的结果
vector<int> num;//用来存储每个数字的次数
};
LeetCode 40
class Solution {
public:
void dfs(int dep, int maxDep, vector<int>& cand, int target)
{
if (target < )return;
if (dep == maxDep)
{
if (target == )
{
vector<int> temp;
for (int i = ; i < maxDep; i++)
{
for (int j = ; j < num[i]; j++)
temp.push_back(cand[i]);
}
res.insert(temp);
}
return;
}
for (int i = ; i<=; i++)
{
num[dep] = i;
dfs(dep + , maxDep, cand, target - i*cand[dep]);
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target)
{
int n = candidates.size();
if (n == )return ret;
sort(candidates.begin(), candidates.end());
num.resize(n);
ret.clear();
dfs(, n, candidates, target);
set<vector<int>>::iterator it= res.begin();
for (;it!=res.end();it++)
{
ret.push_back(*it);
}
return ret;
}
private:
vector<vector<int>> ret;
set<vector<int>> res;
vector<int> num;
};
LeetCode 22
backtracking函数书写的一般规则:
(1)函数参数一般要包括位置或者其它(如本题中的还可以剩余左括号个数及左边有多少个左括号没有关闭),这些都是为函数内容作为判断条件,要选择好。
(2)函数开头是函数终止条件(如本题中已经没有左括号可以使用了,故return),并将结束得到的一个结果(元素可以不取的话,则将临时结果变量作为函数的参数<如subset>,每个元素都要取一个结果,则作为类成员)放入result中
(3)就是函数的后半部分,为递归,函数该位置可以放那些元素(循环),每种元素放入后递归下一个位置的元素,当然包括参数的变化。
(1)参数:pos:迭代位置,共有2*n个元素,表示迭代到第几个位置了, left表示左边已经有多少个左括号没有关闭,当left==0时就不能迭代右括号了,remain表示还可以加入左括号的个数,当remain==0的时候,就不能迭代左括号了。
(2)终止条件:当remain==0时,只能加入右括号了,并将这一结果加入最后的结果中
(3)每个位置都只能放入左右括号两种情况,分别取这两种情况,然后进行下一次迭代。
class Solution {
public:
void dfs(int pos, string &str, int left, int remain, int n){ // left表示左边有多少个左括号没有关闭
if(remain == ){ // 左括号使用完毕 故全部为右括号
for(int i = pos; i < *n; i++)
str[i] = ')';
result.push_back(str);
return;
}
if(remain > ){ // remain!=0 说明还可以使用左括号
str[pos] = '(';
dfs(pos+, str, left+, remain-, n);
}
if(left != ){ // left!=0 表示左边还有左括号没有关闭,故可以使用)
str[pos] = ')';
dfs(pos+, str, left-, remain, n);
}
}
vector<string> generateParenthesis(int n) {
string str;
str.resize(*n);
dfs(, str, , n, n);
return result;
}
private:
vector<string> result;
};
Leetcode 77
class Solution {
private:
vector<vector<int>> result;
vector<int> tmp;
public:
void dfs(int dep, const int &n, int k, int count)
{
if (count == k)
{
result.push_back(tmp);
return;
}
if (dep < n - k + count)
{
dfs(dep + , n, k, count);//不取当前数
}
tmp[count] = dep + ; //取当前数
dfs(dep + , n, k, count+);
}
vector<vector<int>> combine(int n, int k)
{
if (k>n)k = n;
tmp.resize(k);
dfs(, n, k, );
return result;
}
};
LeetCode 17
string NumToStr[] = {"", "","abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
class Solution {
private:
string str;
vector<string> result;
public:
int charToInt(char c)
{
int i;
stringstream ss;
ss << c;
ss >> i;
return i;
}
void dfs(int dep, int maxDep, const string &digits)
{
if (dep == maxDep)
{
result.push_back(str);
}
int index = charToInt(digits[dep]);
for (int i = ; i < NumToStr[index].size(); i++)
{
str[dep] = NumToStr[index][i];
dfs(dep+,maxDep,digits);
}
}
vector<string> letterCombinations(string digits)
{
int n = digits.size();
if (n == )return result;
str.resize(n);
dfs(,n,digits);
return result;
}
};
LeetCode 401
class Solution {
vector<int> hour = { , , , }, minute = {,,,,,};
public:
void helper(vector<string> & res, pair<int, int> time, int num, int start_point)
{
if (num == )
{
if (time.second < )
res.push_back(to_string(time.first) + ":0" + to_string(time.second));
else
res.push_back(to_string(time.first) + ":" + to_string(time.second));
return;
}
for (int i = start_point; i < hour.size() + minute.size(); i++)
{
if (i < hour.size())
{
time.first += hour[i];
if (time.first < )
helper(res, time, num - , i + );
time.first -= hour[i];
}
else
{
time.second += minute[i - hour.size()];
if (time.second < )
helper(res,time,num-,i+);
time.second -= minute[i - hour.size()];
}
}
}
vector<string> readBinaryWatch(int num)
{
vector<string> res;
helper(res,make_pair(,),num,);
return res;
}
};
LeetCode 78
class Solution {
public:
vector<int>ans;
vector<vector<int>> res;
vector<vector<int>> subsets(vector<int>& nums) {
if(nums.empty())return res;
sort(nums.begin(),nums.end());
dfs(,ans,nums);
return res;
}
void dfs(int k,vector<int> ans, vector<int> nums)
{
res.push_back(ans);
for(int i=k;i<nums.size();i++)
{
ans.push_back(nums[i]);
dfs(i+,ans,nums);
ans.pop_back();
}
}
};
LeetCode 51
class Solution {
private:
vector<vector<string> > res;
public:
vector<vector<string> > solveNQueens(int n) {
vector<string>cur(n, string(n,'.'));
helper(cur, );
return res;
}
void helper(vector<string> &cur, int row)
{
if(row == cur.size())
{
res.push_back(cur);
return;
}
for(int col = ; col < cur.size(); col++)
if(isValid(cur, row, col))
{
cur[row][col] = 'Q';
helper(cur, row+);
cur[row][col] = '.';
}
}
//判断在cur[row][col]位置放一个皇后,是否是合法的状态
//已经保证了每行一个皇后,只需要判断列是否合法以及对角线是否合法。
bool isValid(vector<string> &cur, int row, int col)
{
//列
for(int i = ; i < row; i++)
if(cur[i][col] == 'Q')return false;
//右对角线(只需要判断对角线上半部分,因为后面的行还没有开始放置)
for(int i = row-, j=col-; i >= && j >= ; i--,j--)
if(cur[i][j] == 'Q')return false;
//左对角线(只需要判断对角线上半部分,因为后面的行还没有开始放置)
for(int i = row-, j=col+; i >= && j < cur.size(); i--,j++)
if(cur[i][j] == 'Q')return false;
return true;
}
};
LeetCode 46
class Solution {
private:
vector<vector<int>> result;
vector<int> visited;
public:
void dfs(int st, int n, vector<int>& v, vector<int>& nums)
{
if (st == n)
{
result.push_back(v);
return;
}
for (int i = ; i < n; i++)
{
if (visited[i] != )
{
visited[i] = ;
v.push_back(nums[i]);
dfs(st + , n,v,nums);
v.pop_back();
visited[i] = ;
}
}
}
vector<vector<int>> permute(vector<int>& nums)
{
int num = nums.size();
visited.resize(num);
vector<int> tmp;
dfs(,num,tmp,nums);
return result;
}
};
LeetCode 47
class Solution {
private:
vector<vector<int>> result;
vector<int> tmpResult;
vector<int> count;
public:
void dfs(int dep, int maxDep, vector<int>& num, vector<int> visited)
{
if (dep == maxDep)
{
result.push_back(tmpResult);
return;
}
for (int i = ; i < num.size(); i++)
{
if (i == )count[dep] = ;
if (!visited[i])
{
count[dep]++;
if (count[dep]> && tmpResult[dep] == num[i])continue;
// 每个位置第二次选数时和第一次一样则continue
visited[i] = ; // 每个位置第二次选择的数时和第一次不一样
tmpResult[dep] = num[i];
dfs(dep + , maxDep, num, visited);
visited[i] = ;
}
}
}
vector<vector<int>> permuteUnique(vector<int> &num)
{
sort(num.begin(), num.end());
tmpResult.resize(num.size());
count.resize(num.size());
vector<int> visited;
visited.resize(num.size());
dfs(, num.size(), num, visited);
return result;
}
};
LeetCode 79
class Solution {
public:
bool dfs(int xi, int yi, string &word, int index, vector<vector<char> > &board, const int &m, const int &n, int **visited){
visited[xi][yi] = ; // 该结点已经访问过了
if(index + < word.size()){
if(xi- >= && visited[xi-][yi]== && board[xi-][yi] == word[index+]){
if(dfs(xi-, yi, word, index+, board, m, n, visited))return true; //深度遍历
visited[xi-][yi] = ; // 这条路行不通 设为未访问 以不影响下面的遍历
}
if(xi+ <m && visited[xi+][yi]== && board[xi+][yi] == word[index+]){
if(dfs(xi+, yi, word, index+, board, m, n, visited))return true;
visited[xi+][yi] = ;
}
if(yi- >= && visited[xi][yi-]== && board[xi][yi-] == word[index+]){
if(dfs(xi, yi-, word, index+, board, m, n,visited)) return true;
visited[xi][yi-] = ;
}
if(yi+ < n && visited[xi][yi+]== && board[xi][yi+] == word[index+]){
if(dfs(xi, yi+, word, index+, board, m, n,visited)) return true;
visited[xi][yi+] = ;
}
return false;
}else return true;
}
void initVisited(int ** visited, const int &m, const int &n){
for(int i = ; i < m; i++)
memset(visited[i], , sizeof(int)*n);
}
bool exist(vector<vector<char> > &board, string word) {
int m = board.size();
int n = board[].size();
int **visited = new int*[m];
for(int i = ; i < m; i++)
visited[i] = new int[n];
for(int i = ; i < m; i++){ // 找到其中的i和j
for(int j = ; j < n; j++){
if(word[] == board[i][j]){
initVisited(visited, m, n);
if(dfs(i, j, word, , board, m, n,visited)) return true;
}
}
}
for(int i = ; i < m; i++)
delete []visited[i];
delete []visited;
return false;
}
};
LeetCode39/40/22/77/17/401/78/51/46/47/79 11道回溯题(Backtracking)的更多相关文章
- 关于Mysql错误:./bin/mysqld_safe --user=mysql& [1] 32710 121003 16:40:22 mysqld_safe Logging to '/var/log/mysqld.log'. 121003 16:40:22 mysqld_s
[root@www]# ./bin/mysqld_safe --user=mysql&[1] 32710[root@www]# 121003 16:40:22 mysqld_safe Logg ...
- 编写程序,计算当n=10000,20000,30000...100000时,π的值.求π的近似公式 π=4*(1-1/3+1/5-1/7+1/9-1/11+1/13-...+1/(2n-1)-1/(2n+1))
该程序是求的 π 近似值,所以随着 i 的增大,值会无线接近于 3.1415926... 代码示例 : package judgment;/** * 编写程序,计算当n=10000,20000,300 ...
- Git - error: RPC failed; result=22, HTTP code = 401 fatal: The remote end hung up unexpectedly
在用Git管理代码版本时,用git push命令提交代码,提示: 有以下几个可能性: Git 版本过低.GitCafe 推荐使用的 Git 版本是 >= 1.7. $ git --version ...
- Linux运维40道精华题
题目 1.什么是运维?什么是游戏运维? 1)运维是指大型组织已经建立好的网络软硬件的维护,就是要保证业务的上线与运作的正常,在他运转的过程中,对他进行维护,他集合了网络.系统.数据库.开发.安全.监控 ...
- HDU 6090 17多校5 Rikka with Graph(思维简单题)
Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...
- HDU 6095 17多校5 Rikka with Competition(思维简单题)
Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...
- HDU 6066 17多校3 RXD's date(超水题)
Problem Description As we all know that RXD is a life winner, therefore he always goes out, dating w ...
- 51单片机晶振11.0592M延时函数
/********************************************** º¯ÊýÃû£ºdelay_ms(uint z) ÑÓʱº¯Êý(12MHZ¾§Õñ) ´Ëº¯ÊýÑ ...
- Leetcode 46 47 Permutation, 77 combination
Permutation class Solution { List<List<Integer>> res = new ArrayList<List<Integer& ...
随机推荐
- Git是如何存储对象的
原文:http://gitbook.liuhui998.com/7_1.html 一.前言 所有的对象都以SHA值为索引用gzip格式压缩存储, 每个对象都包含了对象类型, 大小和内容. Git中存在 ...
- Solr集群更新配置的方式
solr集群中配置文件是经常更新的,频率最高的也就是schema.xml和solrconfig.xml这两个配置文件了,对于更新配置文件之前,我们先了解一下集群项目结构 由于在集群模式下,solrco ...
- ACM/ICPC 之 枚举(POJ1681-画家问题+POJ1166-拨钟问题+POJ1054-讨厌的青蛙)
POJ1681-画家问题 枚举的经典例题,枚举第一行即可,其余行唯一. //画家问题,y表示黄色,w表示白色,怎样让墙上所有方格为y,操作类似熄灯问题poj1222 //memory 136K Tim ...
- Redis Sentinel高可用架构
Redis目前高可用的架构非常多,比如keepalived+redis,redis cluster,twemproxy,codis,这些架构各有优劣,今天暂且不说这些架构,今天主要说说redis se ...
- 使用ssh正向连接、反向连接、做socks代理的方法
ssh -L 219.143.16.157:58080:172.21.163.32:8080 用户名@localhost -p 10142 在 219.143.16.157机器执行 将ssh隧 ...
- 跨浏览器的事件对象-------EventUtil 中的方法及用法
什么是EventUti----封装好的事件对象 在JavaScript中,DOM0级.DOM2级与旧版本IE(8-)为对象添加事件的方法不同 为了以跨浏览器的方式处理事件,需要编写一段“通用代码”,即 ...
- maven加载本地oracle的JDBC驱动
转载自:http://blog.csdn.net/qicyt1812/article/details/13019933 由于oracle商业版权问题,maven不能通过中心资源库直接下载jar包,如果 ...
- [Android进阶]学习AccessibilityService实现微信抢红包插件
在你的手机更多设置或者高级设置中,我们会发现有个无障碍的功能,很多人不知道这个功能具体是干嘛的,其实这个功能是为了增强用户界面以帮助残障人士,或者可能暂时无法与设备充分交互的人们 它的具体实现是通过A ...
- 【leetcode】Reverse Integer(middle)☆
Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 总结:处理整数溢出 ...
- 20145213《Java程序设计》第九周学习总结
20145213<Java程序设计>第九周学习总结 教材学习总结 "五一"假期过得太快,就像龙卷风.没有一点点防备,就与Java博客撞个满怀.在这个普天同庆的节日里,根 ...