leetcode算题打卡
一、括号生成
- 题目:
- 题解(回溯):
class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<string>ans;
dfs(ans,"",0,n);
return ans;
}
void dfs(vector<string>&ans,const string&str,const int&right,const int&left){
if(left==0&&right==0){
ans.emplace_back(str);
return;
}
if(left) dfs(ans,str+"(",right+1,left-1);
if(right) dfs(ans,str+")",right-1,left);
}
};
二、串联所有单词子串
- 题目:
-
题解:
-
方法一(去重全排列+KMP+遍历):
刚看到这道题目时第一反应就是去重全排列出来所有组合然后通过kmp算法和遍历来记录字符串的位置,但这个方法有点费劲个人觉得,代码我就不弄上来了,可以看我们之前的文章拼接一下就行了
-
方法二(滑动窗口):
-
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
//特殊情况直接排除
if(s.empty()||words.empty())return {};
//存放结果的数组
vector<int> result;
//单词数组中的单词的大小,个数,以及总长度
int one_word=words[0].size();
int word_num=words.size();
int all_len=one_word*word_num;
//建立单词->单词个数的映射
unordered_map<string,int> m1;
for(const auto& w:words)m1[w]++;
for(int i=0;i<one_word;++i)
{
//left和rigth表示窗口的左右边界,count用来统计匹配的单词个数
int left=i,right=i,count=0;
unordered_map<string,int>m2;
//开始滑动窗口
while(right+one_word<=s.size())
{
//从s中提取一个单词拷贝到w
string w=s.substr(right,one_word);
right+=one_word;//窗口右边界右移一个单词的长度
if(m1.count(w)==0){//此单词不在words中,表示匹配不成功,然后重置单词个数、窗口边界、以及m2
count=0;
left=right;
m2.clear();
}
else{//该单词匹配成功,添加到m2中
m2[w]++;
count++;
while(m2.at(w)>m1.at(w))//一个单词匹配多次,需要缩小窗口,也就是left右移
{
string t_w=s.substr(left,one_word);
count--;
m2[t_w]--;
left+=one_word;
}
if(count==word_num)result.push_back(left);
}
}
}
return result;
}
};
三、全排列
- 题目:
- 题解(回溯):
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
if(nums.empty()) return{{}};
vector<vector<int>>res;
dfs(res,nums,0);
return res;
}
private:
void dfs(vector<vector<int>>&res,vector<int>&nums,const int&index){
if(index==nums.size()){
res.emplace_back(nums);
return;
}
for(int i=index;i<nums.size();i++){
swap(nums[index],nums[i]);
dfs(res,nums,index+1);
swap(nums[index],nums[i]);
}
}
};
四、全排列2
- 题目:
- 题解:
-方法一:(回溯)
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
if(nums.empty()) return{{}};
vector<vector<int>>res;
vector<int>vaild(nums.size());
vector<int>number;
sort(nums.begin(),nums.end());
dfs(res,nums,0,vaild,number);
return res;
}
private:
void dfs(vector<vector<int>>&res,vector<int>nums,const int&index,vector<int>&vaild,vector<int>&number){
if(index==nums.size()){
res.emplace_back(number);
return;
}
for(int i=0;i<nums.size();i++){
if(vaild[i]||(i>0&&nums[i]==nums[i-1]&&!vaild[i-1]))continue;
number.emplace_back(nums[i]);
vaild[i]=1;
dfs(res,nums,index+1,vaild,number);
vaild[i]=0;
number.pop_back();
// swap(nums[index],nums[i]);
}
}
};
-方法二:(回溯)
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
if(nums.empty()) return{{}};
vector<vector<int>>res;
sort(nums.begin(),nums.end());
dfs(res,nums,0);
return res;
}
private:
void dfs(vector<vector<int>>&res,vector<int>nums,const int&index){
if(index==nums.size()){
res.emplace_back(nums);
return;
}
for(int i=index;i<nums.size();i++){
// if(vaild[i]) continue;
if(i!=index&&nums[i]==nums[index]) continue;
swap(nums[index],nums[i]);
dfs(res,nums,index+1);
// swap(nums[index],nums[i]);
}
}