字符的判重--位运算

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符的判重--位运算相关的知识,希望对你有一定的参考价值。

典型例题:最长无重复字符的串联字符串

在这里插入图片描述


题目解析

此题看完之后,字符相关且不能含重复字符,便能想到用位运算判重,而其中要求的是数组子序列串相连,这就很明显牵扯到组合问题,组合问题,我们可用多种方式枚举组合,可用二进制枚举组合,也可用dfs枚举,而dfs枚举也有两种形式:偏二进制的形式||回溯形式

这题由于最后要求返回一个最长的 无重复字符的字符串,则该字符串长度肯定不会超过26(毕竟也就26个小写字母)所以完全可以通过操控各个字符串的二进制序列来得到答案。

两种形式的dfs解决

dfs回溯形式

class Solution {
public:
    int maxLength(vector<string>& arr) {
//先去掉arr中有重复字符的字符串,由于字符的范围是小写字母--故ASCII差值不会超过26,故可用每一位计数用于判重
vector<int>newArr;
//由于此题最后的最大长度字符串不含重复字符,所以完全可用二进制位代替字符串来进行判重等迅速计算
        //建合要求二进制表
        for(auto &s:arr){
            int check = 0;
            for(auto &ch:s){
                int dist = ch - 'a';
                //一旦出现重复字符则直接跳出,否则继续建表
                if(check&(1<<dist))
                    goto end;
                check |= 1<<dist;
            }
            newArr.push_back(check);
            end:{}   
        }
        size = newArr.size();
dfs(newArr,0,0);
return res;
}
    
private:
int size;
int res = 0;
    int countSize(int t){
        int count = 0;
        while(t){
            t = t&(t-1);
            count++;
        }
        return count;
    }
    void dfs(vector<int>&arr,int x,int pos){
        //由于不确定取几个,每层都把res进行更新
            res = max(res,countSize(x));
        int temp = x;
        //temp回溯,让每一层只负责选择其中一个
        for(int i=pos;i<size;i++){
            if(x&arr[i])
                continue;
            x |= arr[i];
            dfs(arr,x,i+1);
            x = temp;
        }
    }
};

dfs二进制枚举形式

class Solution {
public:
    int maxLength(vector<string>& arr) {
//先去掉arr中有重复字符的字符串,由于字符的范围是小写字母--故ASCII差值不会超过26,故可用每一位计数用于判重
vector<int>newArr;
//由于此题最后的最大长度字符串不含重复字符,所以完全可用二进制位代替字符串来进行判重等迅速计算
        //建合要求二进制表
        for(auto &s:arr){
            int check = 0;
            for(auto &ch:s){
                int dist = ch - 'a';
                //一旦出现重复字符则直接跳出,否则继续建表
                if(check&(1<<dist))
                    goto end;
                check |= 1<<dist;
            }
            newArr.push_back(check);
            end:{}   
        }
        size = newArr.size();
dfs(newArr,0,0);
return res;
}
    
private:
int size;
int res = 0;
    int countSize(int t){
        int count = 0;
        while(t){
            t = t&(t-1);
            count++;
        }
        return count;
    }
    //取与不取相当于1和0,所以很像二进制枚举
    void dfs(vector<int>&arr,int x,int pos){
        //相当于取完了这一次的所有位置,即相当于取完了一个二进制串如01011
        if(pos==size){
            res = max(res,countSize(x));
            return;
        }
        //取该位元素
        if(!(x&arr[pos]))
            dfs(arr,x|arr[pos],pos+1);
        //不取该位元素,到下一位
        dfs(arr,x,pos+1);
    }
};

以上是关于字符的判重--位运算的主要内容,如果未能解决你的问题,请参考以下文章

海量数据分析处理方法

介绍一下海量数据的处理方法

10个JavaScript代码片段,使你更加容易前端开发。

10个JavaScript代码片段,使你更加容易前端开发。

寒假总结。。。

0x20 搜索