刷题日记1

2024.12.24 

2134. 最少交换次数来组合所有的 1 II

class Solution {
public:
    int minSwaps(vector<int>& nums) {
        //先找1的长度k,再滑k,找到最大值,返回k-sum
        int k=0;
        for(int i=0;i<nums.size();i++)k+=nums[i];
        int res=0,sum=0,n=nums.size();
        for(int i=0;i<k-1;i++)sum+=nums[i];
        for(int i=k-1;i<k-1+n&&i>=0;i++){
            //进
            sum+=nums[i%n];
            //处理
            res=max(res,sum);
            //出
            sum-=nums[i-k+1];
        }
        return k-res;
    }
};

思考:正常套路处理,会遇到k=0的情况,导致数组越界。没有太关注这个。需要注意

67. 二进制求和

class Solution {
public:
    string addBinary(string a, string b) {
        //倒序遍历计算,i值a, j值b
        int an=a.size(),bn=b.size();
        if(an>bn){
            for(int i=1;i<=an-bn;i++) b='0'+b;
        }
        else {
            for(int i=1;i<=bn-an;i++) a='0'+a;
        }
        int next=0;
        for(int i=max(an-1,bn-1);i>=0;i--){
            int sum=0;
            sum+=next+(a[i]-'0')+(b[i]-'0');
            next=sum/2;
            sum=sum%2;
            b[i]=sum+'0';
        }
        if(next==1) {
            b='1'+b;
        }
        return b;
    }
};

思考:确实好坑。主要就考察对字符串的处理把。1.如何将字符'2'转换成整数2呢?'2'-'0'即可。

2.如何将整数2转换为字符'2'呢?2+'0'即可。因为'0'的ascii码是48,50对应字符'2'。3.最好先给两个字符串补齐,我没补齐刚开始,遍历的时候有点点复杂。

2024.12.26

2653. 滑动子数组的美丽值

class Solution {
public:
    vector<int> getSubarrayBeauty(vector<int>& nums, int k, int x) {
        //维护count数组,存对应负数的个数
        //维护cnt,计数负数的值
        //若cnt<x,则美丽值为0;反之,在coumt数组中找
        int cnt=0;
        vector<int>count(50,0);
        vector<int>res;
        for(int i=0;i<nums.size();i++){
            //进
            if(nums[i]<0){
                cnt++;
                count[nums[i]+50]++;
            }
            if(i<k-1)continue;//先建立滑动窗口
            //进行处理
            if(cnt<x){
                res.push_back(0);
            }
            else{
                int left=x;
                for(int j=0;j<50;j++){
                    left-=count[j];
                    if(left<=0){
                        //结果就是j对应的值
                        res.push_back(j-50);
                        break;
                    }
                }
            }
            //处理完更新滑动窗口   出
            if(nums[i-k+1]<0){
                cnt--;
                count[nums[i-k+1]+50]--;
            }
        }
        return res;
    }
};

思考:1.对我还是挺难的,排除刚开始题目看错,“第x小的值”,而不是“第x个值”。

2.滑动窗口只维护负数值

3.根据数组顺序查找第x小。

567. 字符串的排列

class Solution {
public:
        //统计s1各字符长度,
        //以s1长度在s2进行滑动窗口
        //滑动过程中维护
        unordered_map<char,int>s1map;
        unordered_map<char,int>s2map;
        
    bool istrue(){
        //如何判断为true
        if(s1map.size()!=s2map.size()) return false;
        for(auto [key,val]:s1map){
            if(s2map[key]!=val) return false;
        }
        return true;
    }
    bool checkInclusion(string s1, string s2) {
        int s1sum=0,s2sum=0;//ascii值总和
        int k=s1.size();//滑动窗口长度
        for(int i=0;i<k;i++){
            s1sum+=s1[i]-'a'+1;
            s1map[s1[i]]++;
        }
        //遍历s2
        for(int i=0;i<s2.size();i++){
            //先初始化一个窗口
            s2sum+=s2[i]-'a'+1;
            s2map[s2[i]]++;
            if(i<k-1)continue;
            //进行处理
            if(s1sum==s2sum){
                if(istrue()){
                    return true;
                }
            }
            //出操作
            s2sum-=s2[i-k+1]-'a'+1;
            if(!(--s2map[s2[i-k+1]])) s2map.erase(s2[i-k+1]);
        }
        return false;
    }
};

思考:1.思路差不多,但是处理判断结果那一部分不太行。就是对map的遍历

438. 找到字符串中所有字母异位词

class Solution {
public:
    unordered_map<char,int>pmap;
    unordered_map<char,int>smap;
    bool istrue(){
        if(pmap.size()!=smap.size()) return false;
        for(auto [key,val]:pmap){
            if(smap[key]!=val) return false;
        }
        return true;
    }
    vector<int> findAnagrams(string s, string p) {
        //和上一题几乎一样,就是处理改成将索引压入数组
        int k=p.size();
        vector<int>res;
        //先统计p的字符个数
        for(int i=0;i<k;i++){
            pmap[p[i]]++;
        }
        //遍历p
        for(int i=0;i<s.size();i++){
            //先初始化滑动窗口
            smap[s[i]]++;
            if(i<k-1)continue;
            //处理
            if(istrue()){
                res.push_back(i-k+1);
            }
            //出
            if(!(--smap[s[i-k+1]])) smap.erase(s[i-k+1]);
        }
        return res;
    }
};

思考:1.做过上一题后,这题就很简单,几乎一样,就是处理结果不一样。

2.很抓马的事情就是这题和上题要遍历的字符串反过来了,没注意,找错了好久。

2024.12.28

3. 无重复字符的最长子串

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        //用某结构保存字符个数,
        //对s遍历,如果该字符已经被保存,就将结构清零,保存此时最大长度,重新保存该字符
        int res=0;
        int l=0;//左端点
        int r=0;
        unordered_set<char>set;
        for(;r<s.size();){
            if(set.find(s[r])==set.end()){
                //没找到,就插入
                set.insert(s[r]);
                int len=r-l+1;
                res=max(res,len);
                r++;
            }
            else{
                
                set.erase(s[l]);
                l++;
            }
        }
        return res;
    }
};

思考:for循环还能这样用,手动控制指针的自增。从而实现删除之前保存维护的字符。

不是找到重复的就把前面的全部删除,从此刻字符重新统计。而是从l开始向右一直删,直到删把重复的那个字符给删掉。即,删除重复的字符及之前的。

3090. 每个字符最多出现两次的最长子字符串

class Solution {
public:
    int maximumLengthSubstring(string s) {
        int n=s.size();
        int res=0,l=0;
        unordered_map<char,int>map;
        for(int i=0;i<s.size();i++){
            map[s[i]]++;
            while(map[s[i]]>2){//一直删除前面的,直到该字符map的val==2
            //及时前面的有些字符是没超过2
                map[s[l]]--;
                l++;
            }
            res=max(res,i-l+1);
        }
        return res;
    }
};

思考:这个是字符统计大于2时,从l往右一直删,直到此时的字符==2。即删除字符统计为3的第一次出现的位置及之前的所有字符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值