[算法专题] 深度优先搜索&回溯剪枝
2015-08-08 11:05
447 查看
1. Palindrome Partitioning
https://leetcode.com/problems/palindrome-partitioning/Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s =
%26quot;aab%26quot;,
Return
[ [%26quot;aa%26quot;,%26quot;b%26quot;], [%26quot;a%26quot;,%26quot;a%26quot;,%26quot;b%26quot;] ]
/** * author : Jianxin Zhou * email:zhoujx0219@163.com * * 该题dfs函数原型如下: * void partitionHelper(const string %26amp;s, vector%26lt;vector%26lt;string%26gt;%26gt; %26amp;result, vector%26lt;string%26gt; %26amp;path, int pos) * * 以aaba举例。 * 1. 首先a为回文,然后对aba进行dfs * 2. 之后回溯到a时,以aa为回文,然后对ba做dfs * 3. 回溯到aa,试图以aab为回文,失败;试图以aaba为回文失败;结束。 * * 注意:如果能顺利的找到一组回文,那么pos最终会等于s.size(),此时可以push到result。 * 如果找不到,例如之前的aaba不是回文,那么就会直接退出循环,没有机会执行下一步递归,也就没有pos等于s.size了。 * * 实际上,此类题与真正的dfs的差别在于,dfs在回溯时,不会进行剪枝操作。而此类题,由于需要求出所有方案,所以需要剪枝。 * */ class Solution { public: vector%26lt;vector%26lt;string%26gt;%26gt; partition(string s) { vector%26lt;vector%26lt;string%26gt;%26gt; result; vector%26lt;string%26gt; path; partitionHelper(s, result, path, 0); return result; } private: void partitionHelper(const string %26amp;s, vector%26lt;vector%26lt;string%26gt;%26gt; %26amp;result, vector%26lt;string%26gt; %26amp;path, int pos) { // base case if (pos == s.size()) { result.push_back(path); return; } for (int i = pos; i %26lt; s.size(); i++) { if (isPalindrome(s, pos, i)) { path.push_back(s.substr(pos, i - pos + 1)); partitionHelper(s, result, path, i + 1); path.pop_back(); } } } bool isPalindrome(const string %26amp;s, int start, int end) { while (start %26lt; end) { if (s[start] == s[end]) { start++; end--; } else { break; } } return start %26gt;= end; } };
2. Permutations
https://leetcode.com/problems/permutations/Given a collection of numbers, return all possible permutations.
For example,
[1,2,3]have the following permutations:
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2], and
[3,2,1].
具体可参加我之前写的文章:[LintCode] Permutations
/** * 思路:dfs。 * * 以123举例, * 1. 首先以1作为head,然后对23做dfs * 2. 回溯到1, 以2作为head,对13做dfs * 3. 最后回溯到2,以3作为head,对12做dfs * * 注意:例如以2为head,对其余元素做dfs时,那么2不能再取,因此在进行下一轮dfs时,需要标记2为以访问过 * */ class Solution { public: vector%26lt;vector%26lt;int%26gt;%26gt; permute(vector%26lt;int%26gt;%26amp; nums) { vector%26lt;vector%26lt;int%26gt;%26gt; result; vector%26lt;int%26gt; path; bool visited[nums.size()]; for(int i = 0; i %26lt; nums.size(); i++) { visited = false; } sort(nums.begin(), nums.end()); dfs(nums, result, path, visited); return result; } private: void dfs(const vector%26lt;int%26gt; %26amp;nums, vector%26lt;vector%26lt;int%26gt;%26gt; %26amp;result, vector%26lt;int%26gt; %26amp;path, bool visited[]) { // base case if (path.size() == nums.size()) { result.push_back(path); return; } for (int i = 0; i %26lt; nums.size(); i++) { if (visited[i] == false) { path.push_back(nums[i]); visited[i] = true; dfs(nums, result, path, visited); path.pop_back(); visited[i] = false; } } } };
3. Permutations II
https://leetcode.com/problems/permutations-ii/Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2]have the following unique permutations:
[1,1,2],
[1,2,1], and
[2,1,1].
要点在于保证相同的数不在同一位置出现两次以上,可以参见我写的这篇文章:[LintCode] Permutations II
class Solution { public: /** * @param nums: A list of integers. * @return: A list of unique permutations. */ vector%26lt;vector%26lt;int%26gt; %26gt; permuteUnique(vector%26lt;int%26gt; %26amp;nums) { // write your code here vector%26lt;vector%26lt;int%26gt;%26gt; paths; if (nums.empty()) { return paths; } sort(nums.begin(), nums.end()); bool *visited = new bool[nums.size()](); vector%26lt;int%26gt; path; permuteUniqueHelper(nums, visited, path, paths); return paths; } private: void permuteUniqueHelper(const vector%26lt;int%26gt; %26amp;nums, bool visited[], vector%26lt;int%26gt; %26amp;path, vector%26lt;vector%26lt;int%26gt;%26gt; %26amp;paths) { if (path.size() == nums.size()) { paths.push_back(path); return; } for (int ix = 0; ix %26lt; nums.size(); ix++) { if (visited[ix] == true || ix %26gt; 0 %26amp;%26amp; nums[ix - 1] == nums[ix] %26amp;%26amp; visited[ix - 1] == false) { continue; } visited[ix] = true; path.push_back(nums[ix]); permuteUniqueHelper(nums, visited, path, paths); visited[ix] = false; path.pop_back(); } } };
4 Subsets
https://leetcode.com/problems/subsets/Given a set of distinct integers, [i]nums, return all possible subsets.
Note:
Elements in a subset must be in non-descending order.
The solution set must not contain duplicate subsets.
For example,
If nums =
[1,2,3], a solution is:
[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
/** * 思路:找方案,一般都是使用搜索。 * * 以123为例,在递归还没有开始前,先把空集push到result中,之后: * 1. 以1位hea a1fe d,对23做dfs,所以pos需要加1,用于分支限界(1 12 13 123) * 2. 回溯到1,以2为head,对3做dfs (2 23) * 3. 回溯到3,以3为head,之后循环结束。 (3) * * */ class Solution { public: vector%26lt;vector%26lt;int%26gt;%26gt; subsets(vector%26lt;int%26gt;%26amp; nums) { // ensure that elements in a subset must be in non-descending order. sort(nums.begin(), nums.end()); vector%26lt;vector%26lt;int%26gt;%26gt; res; vector%26lt;int%26gt; path; dfs(nums, res, path, 0); return res; } private: void dfs(const vector%26lt;int%26gt; %26amp;nums, vector%26lt;vector%26lt;int%26gt;%26gt; %26amp;res, vector%26lt;int%26gt; %26amp;path, int pos) { res.push_back(path); for (int i = pos; i %26lt; nums.size(); i++) { path.push_back(nums); dfs(nums, res, path, i + 1); path.pop_back(); } } };
5. Subsets II
https://leetcode.com/problems/subsets-ii/Given a collection of integers that might contain duplicates, [i]nums, return all possible subsets.
Note:
Elements in a subset must be in non-descending order.
The solution set must not contain duplicate subsets.
For example,
If nums =
[1,2,2], a solution is:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
同一位置上,前面取过的数,后面就不要再重复取了,当然当i = pos时,这个数必然是第一次取。
class Solution { public: vector%26lt;vector%26lt;int%26gt;%26gt; subsetsWithDup(vector%26lt;int%26gt; %26amp;nums) { sort(nums.begin(), nums.end()); vector%26lt;vector%26lt;int%26gt;%26gt; res; vector%26lt;int%26gt; path; dfs(nums, res, path, 0); return res; } private: void dfs(const vector%26lt;int%26gt; %26amp;nums, vector%26lt;vector%26lt;int%26gt;%26gt; %26amp;res, vector%26lt;int%26gt; %26amp;path, int pos) { res.push_back(path); for (int i = pos; i %26lt; nums.size(); i++) { if (i != pos %26amp;%26amp; nums[i] == nums[i - 1]) { continue; } path.push_back(nums[i]); dfs(nums, res, path, i + 1); path.pop_back(); } } };
(未完待续)
相关文章推荐
- KEPServerEx OPC 读取西门子 PLC S7200 SMART的数据
- 解决Please ensure that adb is correctly located at '\sdk\platform-tools\adb.exe' and can be executed错误
- [算法专题] 深度优先搜索&回溯剪枝
- 南邮 OJ 2075 特技的幂
- HDU 1863 畅通工程
- Cocos2D游戏之旅(四):卡牌翻转效果的实现(下)
- wordpress常见的问题
- [算法专题] 深度优先搜索&回溯剪枝
- android平台获取手机IMSI,IMEI ,序列号,和 手机号的方法
- Road System HUST 1631 最小生成树
- Java容器
- c++自定义string类
- activemq in action
- 取石子游戏(hdu2516+FIB博弈)
- 面试题:在一个数组中除两个数字只出现1次外,其它数字都出现了2次, 要求尽快找出这两个数字
- ORACLE 定时执行存储过程
- [算法专题] 深度优先搜索&回溯剪枝
- 南邮 OJ 2074 pdf的旅游
- windows server 2008 R2设置远程访问用户数
- 3126POJ