一: LeetCode39 Combination
Sum
题目:
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where
the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
- All numbers (including target) will be positive integers.
- Elements in a combination (a1, a2,
… , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤
… ≤ ak). - The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7
and target 7
,
A solution set is:
[7]
[2, 2, 3]
链接:https://leetcode.com/problems/combination-sum/
分析:此题刚开始想到的类似于背包问题,然而背包的话,打印结果比较困难,因此只能使用回溯。注意此题给的C是一个set,因此元素互不相同
class Solution { public: void dfs(int dep, int maxDep, vector<int> &cand, int target){ // 核心 if(target < 0) return; if(dep == maxDep){ if(target == 0){ vector<int> temp; for(int i = 0; i < maxDep; i++){ for(int j = 0; j < num[i]; j++) temp.push_back(cand[i]); } ret.push_back(temp); } return; } for(int i = 0; i <= target/cand[dep]; i++){ num[dep] = i; dfs(dep+1, maxDep, cand, target-i*cand[dep]); } } vector<vector<int> > combinationSum(vector<int> &candidates, int target) { int n = candidates.size(); if(n == 0) return ret; sort(candidates.begin(), candidates.end()); // 有序输出 num.resize(n); ret.clear(); dfs(0, n, candidates, target); return ret; } private: vector<vector<int> > ret; // 返回的结果 vector<int> num; // 用来存储每个数字的次数 };
二:LeetCode40 Combination
Sum II
题目:
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where
the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
- All numbers (including target) will be positive integers.
- Elements in a combination (a1, a2,
… , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤
… ≤ ak). - The solution set must not contain duplicate combinations.
For example, given candidate set 10,1,2,7,6,1,5
and target 8
,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]
链接:https://leetcode.com/problems/combination-sum-ii/
分析:此题是上一题的变形,只需对每个元素取0或者1次,但是出现的问题是集合中可能有重复的元素,因此需要该进,该进点在于当前元素与前一个元素相等时,只有当前一个元素取的时候,必须取当前元素
class Solution { public: void dfs(int dep, int maxDep, int target, vector<int> &cand){ if(target < 0) return; if(dep == maxDep){ if(target == 0){ vector<int> temp; for(int i = 0; i < maxDep; i++) { for(int j = 0; j < num[i]; j++) temp.push_back(cand[i]); } ret.push_back(temp); } return; } for(int i = 0; i <= 1; i++){ if(dep-1 >= 0 && cand[dep]==cand[dep-1] && num[dep-1] == 1)i = 1; //有相同元素,前面一个元素取到的时候,后面一个元素必须取 num[dep] = i; dfs(dep+1, maxDep, target-i*cand[dep], cand); } } vector<vector<int> > combinationSum2(vector<int> &candidates, int target) { int n = candidates.size(); if(n == 0) return ret; sort(candidates.begin(), candidates.end()); num.resize(n); ret.clear(); dfs(0, n, target, candidates); return ret; } private: vector<int> num; // 用来存储每个数字的次数 vector<vector<int> > ret; // // 返回的结果 };
三:Word Search
题目:
Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
For example,
Given board =
[ ["ABCE"], ["SFCS"], ["ADEE"] ]
word = "ABCCED"
,
-> returns true
,
word = "SEE"
,
-> returns true
,
word = "ABCB"
,
-> returns false
.
链接:https://leetcode.com/problems/word-search/
分析:这题就是dfs的思想,需要回溯。
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] = 1; // 该结点已经访问过了 if(index + 1 < word.size()){ if(xi-1 >= 0 && visited[xi-1][yi]==0 && board[xi-1][yi] == word[index+1]){ if(dfs(xi-1, yi, word, index+1, board, m, n, visited))return true; //深度遍历 visited[xi-1][yi] = 0; // 这条路行不通 设为未访问 以不影响下面的遍历 } if(xi+1 <m && visited[xi+1][yi]==0 && board[xi+1][yi] == word[index+1]){ if(dfs(xi+1, yi, word, index+1, board, m, n, visited))return true; visited[xi+1][yi] = 0; } if(yi-1 >= 0 && visited[xi][yi-1]==0 && board[xi][yi-1] == word[index+1]){ if(dfs(xi, yi-1, word, index+1, board, m, n,visited)) return true; visited[xi][yi-1] = 0; } if(yi+1 < n && visited[xi][yi+1]==0 && board[xi][yi+1] == word[index+1]){ if(dfs(xi, yi+1, word, index+1, board, m, n,visited)) return true; visited[xi][yi+1] = 0; } return false; }else return true; } void initVisited(int ** visited, const int &m, const int &n){ for(int i = 0; i < m; i++) memset(visited[i], 0, sizeof(int)*n); } bool exist(vector<vector<char> > &board, string word) { int m = board.size(); int n = board[0].size(); int **visited = new int*[m]; for(int i = 0; i < m; i++) visited[i] = new int[n]; for(int i = 0; i < m; i++){ // 找到其实的i和j for(int j = 0; j < n; j++){ if(word[0] == board[i][j]){ initVisited(visited, m, n); if(dfs(i, j, word, 0, board, m, n,visited)) return true; } } } for(int i = 0; i < m; i++) delete []visited[i]; delete []visited; return false; } };