Leetcode学习计划-算法入门第11天
题目77:给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
方案:用递归的方法,用两个数组,一个数组用来生成符合条件的组合,另一个数组将组合存放到一起输出,首先是终止条件的判断,可以用减法也可以用加法,用减法的时候相当于递归过程中没增加一个值目标长度-1,当目标长度为0时即为符合条件的组合,用加法的时候需要考虑每个当前位置取和不取两种情况。
class Solution {
public:
void back_track(vector<vector<int>>&combinations,vector<int>&combination,int n,int k){
if(k==0){
combinations.push_back(combination);
}
for(int i=n;i>0;i--){
combination.push_back(i);
back_track(combinations,combination,i-1,k-1);
combination.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
vector<vector<int>>combinations;
vector<int>combination;
back_track(combinations,combination,n,k);
return combinations;
}
};
参考官方解法,递归+剪枝
class Solution {
public:
void back_track(vector<vector<int>>&combinations,vector<int>&combination,int cur,int n,int k){
if(combination.size()+n-cur+1<k){
return;
}
if(combination.size()==k){
combinations.push_back(combination);
return;
}
#有当前值的组合
combination.push_back(cur);
back_track(combinations,combination,cur+1,n,k);
combination.pop_back();
#没有当前值的组合
back_track(combinations,combination,cur+1,n,k);
}
vector<vector<int>> combine(int n, int k) {
vector<vector<int>>combinations;
vector<int>combination;
back_track(combinations,combination,1,n,k);
return combinations;
}
};
题目46:给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
方案:与上题的思路一致,只是要求全排列,说明全部值都要出现而且只能出现一次,因此使用visited数组来表示当前值是否已经进入到集合中,通过这个访问标志可以避免将重复值放入到全排列之中。
class Solution {
vector<vector<int>>combinations;
vector<int>combination;
public:
void dfs(vector<int>&visited,vector<int>&nums,int n){
if(combination.size()==n){
combinations.push_back(combination);
return;
}
for(int i=0;i<n;i++){
if(visited[i]==1)continue;
visited[i]=1;
combination.push_back(nums[i]);
dfs(visited,nums,n);
combination.pop_back();
visited[i]=0;
}
}
vector<vector<int>> permute(vector<int>& nums) {
int n=nums.size();
vector<int>visited(n,0);
dfs(visited,nums,n);
return combinations;
}
};
当然还有其他解法,比如官方提供的递归替换的方法。
class Solution {
vector<vector<int>>combinations;
public:
void dfs(vector<int>&nums,int first,int n){
if(first==n){
combinations.push_back(nums);
}
for(int i=first;i<n;i++){
swap(nums[first],nums[i]);
dfs(nums,first+1,n);
swap(nums[first],nums[i]);
}
}
vector<vector<int>> permute(vector<int>& nums) {
int n=nums.size();
vector<int>visited(n,0);
dfs(nums,0,n);
return combinations;
}
};
题目784:给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串。返回所有可能得到的字符串集合。
方案:递归
用python写一下子
class Solution:
def letterCasePermutation(self, s: str) -> List[str]:
ans=[]
def dfs(ans,s,first,lens):
if(first==lens):
ans.append(s)
return
if s[first].isupper():
dfs(ans,s[:first]+s[first].lower()+s[first+1:],first+1,lens)
if s[first].islower():
dfs(ans,s[:first]+s[first].upper()+s[first+1:],first+1,lens)
dfs(ans,s,first+1,lens)
dfs(ans,s,0,len(s))
return ans
来源:leetcode