算法刷题计划(十三)括号生成、串联所有单词子串、全排列、全排列2

22 篇文章 0 订阅
20 篇文章 0 订阅

一、括号生成

  • 题目:

在这里插入图片描述


  • 题解(回溯):
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]);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值