c++算法第六天

本篇文章我们继续学习c++的算法

目录

第一题

题目链接

题目解析

理解题意的方法

关键词

画图

代码原理

题意转化

代码原理

暴力枚举

滑动窗口

代码编写

第二题

题目链接

题目解析

代码原理

代码编写

第三题

题目链接

题目解析

代码原理

代码编写


第一题

题目链接

. - 力扣(LeetCode)

题目解析

理解题意的方法
关键词

每次操作,删除数组最左边或最右边的元素,然后从x中减去这些被删除的元素,当x==0时,返回最小操作数。

画图

那么这里的画图是根据题目和例子进行绘画的。

20241101_160512

代码原理

题意转化

代码原理
暴力枚举

滑动窗口

代码编写

class Solution {

public:

    int minOperations(vector<int>& nums, int x) {

        int n = 0,target = 0, len = -1;//数组所有元素之和

        for(int cur: nums)

        {

            n += cur;

        }

        if(target < 0)

        return -1;

        int left = 0, right = 0, sum = 0;

        target = n - x;

        while(right < nums.size())

        {

            sum += nums[right];//进窗口

            while(sum > target && left  < nums.size())//判断,其中left < nums.size()的作用是防止越界

            {

                sum -= nums[left++];//出窗口

            }

            if(sum == target)

            {

                len = max(len, right - left + 1);

            }

            right++;

        }

        if(len == -1)

        {

            return len;

        }

        else

        return nums.size() - len;

    }

};

第二题

题目链接

904. 水果成篮 - 力扣(LeetCode)

题目解析

题目要求:只有两个篮子,每个篮子只能装单一类型的水果,通俗讲就是一个子数组内只能由两种不同的数字如[ 1,2,1,1,1,1,1],那么这个例子就是合法的,不合法的例子[1,2,1,1,1,3],采摘完一棵树就右移,最后返回最大的子数组长度

相信大家看完这个例子就能明白题目要求了

代码原理

从上面我们的就可以得到暴力解法的思路了。

1.定义left和right

2.判断子数组内有多少个不同的数字(这里要用到hash!)

3.如果小于或等于两个则right右移,否则left移动

其中2和3两步是循环的

当跳出循环时跟新最大的长度

但是暴力解法有个弊,这个弊端就是每次移动了left,right就会又回到left处重新开始遍历

那么滑动窗口就是left移动right也不会回到left处重新开始遍历,这就是滑动窗口与暴力解法的区别

代码编写

class Solution {

public:

    int totalFruit(vector<int>& fruits) {

        unordered_map<int,int>hash;

        int ret = 0;

        for(int left = 0, right = 0; right < fruits.size(); right++)

        {

            hash[fruits[right]]++;//进窗口

            while(hash.size() > 2)//判断

            {

                hash[fruits[left]]--;//出窗口

                if(hash[fruits[left]] == 0)

                {

                    hash.erase(fruits[left]);

                }

                left++;

            }

            ret = max(ret, right - left + 1);//更新长度

        }

        return ret;

    }

};

第三题

题目链接

438. 找到字符串中所有字母异位词 - 力扣(LeetCode)

题目解析

代码原理

 

代码编写

class Solution {

public:

    vector<int> findAnagrams(string s, string p) {

        vector<int> ret;

        int hash1[26] = {0};

        for(auto cur : p)

        {

            hash1[cur - 'a']++;

        }

        int m = p.size();

        int hash2[26] = {0};

        for(int left = 0, right = 0, count = 0; right < s.size(); right++)

        {

            char in = s[right];

            if(++hash2[in - 'a'] <= hash1[in - 'a'])//进窗口

            count++;//维护count

            if(right - left + 1 > m)//判断

            {

                //出窗口

                char out = s[left++];

                if(hash2[out - 'a'] <= hash1[out - 'a'])

                count--;

                hash2[out - 'a']--;

            }

            //更新结果

            if(count == m)

              ret.push_back(left);

        }

        return ret;

    }

};

本篇文章的算法题练习就先到这里,我们下期文章再见!!!

记得给个三联哦!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值