leetcode中的bitmap

C++中常用的bitmap数据结构

bitset
相关函数set() count() any() none()

1239. 串联字符串的最大长度

给定一个字符串数组 arr,字符串 s 是将 arr 某一子序列字符串连接所得的字符串,如果 s 中的每一个字符都只出现过一次,那么它就是一个可行解。
请返回所有可行解 s 中最长长度。

1、要是子序列中有重复的字符,则不合法,跳过该子序列
2、子字符串要是和之前的合法的字符串无重复字符,则加到总序列中,并更新最大合法序列长度。

class Solution {
public:
    int maxLength(vector<string>& arr) {
        vector<bitset<26>> allS = {bitset<26>()};
        int res=0;
        for(auto& s:arr){
            bitset<26> a;
            for(char c:s){
                a.set(c-'a'); 
                }               
                int n=a.count();
                if(n<s.length()) //如果字符串本身是有重复的,则跳过后面的统计
                    continue;
                for(int i=allS.size()-1;i>=0;i--){
                    bitset<26> b=allS[i];
                    if((b&a).any()){//如果当前字符与之前的字符有重复,则跳过
                        continue;
                    }
                    allS.push_back(b|a);//保存新的更长的字符
                    res=max(res,int(n+b.count()));//更新合法字符的最长长度

            }
        }
        return res;
    }
};
992. K 个不同整数的子数组

给定一个正整数数组 A,如果 A 的某个子数组中不同整数的个数恰好为 K,则称 A 的这个连续、不一定独立的子数组为好子数组。
(例如,[1,2,3,1,2] 中有 3 个不同的整数:1,2,以及 3。)
返回 A 中好子数组的数目。

在这里插入图片描述

class Solution {
public:
    int subarraysWithKDistinct(vector<int>& A, int K) {
        return atmostk(A,K)-atmostk(A,K-1);//不重复且长度恰好为k的子数组=最多不重复且长度为k-不重复最多为k-1
    }
    int atmostk(vector<int>& A,int k){
        int res=0,j=0;
        unordered_map<int,int>map;//map用来存放重复最多为k的字符,也就是窗口
        for(int i=0;i<A.size();++i){
            if(!map[A[i]]++)k--;//k用来控制窗口的长度,
            while(k<0){//长度如果大于k
                if(!--map[A[j]])//减去窗口重复的字符,--在前面是为了只减去重复的,j相当于按照原始字符串的顺序找重复的数值,把重复的数减掉控制滑动窗口的长度为1;
                    k++;//减去字符后窗口减去1
                j++;//j相当于统计了k<0的子数组的数目,这部分减掉
            }
            res+=i-j+1;//i从0开始,所以加1
        }
        return res;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值