17.電話號碼的字母組合
class Solution {
public:
string mp[10] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
vector<string> ans;
vector<string> letterCombinations(string digits) {
int n = digits.size();
if (n == 0) return {};
string p(n, 0);
function<void(int)> dfs = [&](int u) {//當前列舉到第u位
if (u == n) {//列舉到最後一位的後一位,說明選擇字元結束,將
ans.push_back(p);
return;
}
for (auto c : mp[digits[u] - '0']) {
p[u] = c;//直接覆蓋
dfs(u + 1);//列舉下一位
}
};
dfs(0);//從第0位開始列舉
return ans;
}
};
78.子集
思考角度一、考慮每個數選或不選,這樣列舉到 \(i\) = \(n\) 時說明所有情況考慮完畢,退出 \(\rm dfs\)
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> ans;
if (n == 0) return {};
vector<int> p;
function<void(int)> dfs = [&](int i) {//列舉第i個數選或不選
if (i == n) {
ans.push_back(p);
return;
}
dfs(i + 1);//不選這個數,直接跳過,列舉下一個數
p.push_back(nums[i]);//選這個數
dfs(i + 1);
p.pop_back();//恢復現場
};
dfs(0);
return ans;
}
};
思考角度二、
從答案的角度考慮:列舉第 \(i\) 個位置應該選原陣列中的哪個數。(\(i\) 表示列舉的起點)
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> ans;
vector<int> p;
function<void(int)> dfs = [&](int i) {
ans.push_back(p);
if (i == n) return;//由於i = n時不進入迴圈,這行可以省略
for (int j = i; j < n; j++) {
p.push_back(nums[j]);
dfs(j + 1);
p.pop_back();
}
};
dfs(0);
return ans;
}
};
131.分割回文串
思考角度一、假設每對相鄰字元之間有個逗號,那麼就看每個逗號是選還是不選。
class Solution {
public:
bool is(string a, int l, int r) {
while (l < r) {
if (a[l++] != a[r--]) return false;
}
return true;
}
vector<vector<string>> partition(string s) {
vector<vector<string>> ans;
vector<string> p;
int n = s.size();
function<void(int, int)> dfs = [&](int i, int u) {//i表示起始位置,u表示當前列舉到的位置
if (u == n) {
ans.push_back(p);
return;
}
if (u != n - 1) dfs(i, u + 1);
if (is(s, i, u)) {
p.push_back(s.substr(i, u - i + 1));
dfs(u + 1, u + 1);
p.pop_back();
}
};
dfs(0, 0);
return ans;
}
};
思考角度二、依次列舉每個字串結束(逗號)的具體位置
class Solution {
public:
bool is(string a, int l, int r) {
while (l < r) {
if (a[l++] != a[r--]) return false;
}
return true;
}
vector<vector<string>> partition(string s) {
int n = s.size();
vector<vector<string>> ans;
vector<string> p;
function<void(int)> dfs = [&](int i) {
if (i == n) {
ans.push_back(p);
return;
}
for (int j = i; j < n; j++) {
if (is(s, i, j)) {
p.push_back(s.substr(i, j - i + 1));
dfs(j + 1);
p.pop_back();
}
}
};
dfs(0);
return ans;
}
};