代码随想录数组-长度最小的子数组

首先自己做法,想到了之前用的一个快速排序,于是解法:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int sum = 0;
        int length = 0;
        sort(nums.begin(), nums.end());
        for (int i = nums.size() - 1; i >= 0; i--){
            sum += nums[i];
            if (sum >= target){
                length = nums.size() - i ;
                break;
            }
        }
        return length;
    }
};

但是该解法在第18个用例处报错了,不知道是什么原因

target =
213
nums =
[12,28,83,4,25,26,25,2,25,25,25,12]

添加到测试用例
输出
7
预期结果
8

费解,我手算这个结果也是7,在VSCODE中调试也没发现什么问题,用暴力解法运行竟然能过,我仔细研究下。

其次是暴力解法。

暴力解法看着看着我突然明白了,原来这题要的是“长度最小的子数组”,要是连号的,没仔细审题。。导致研究了这么久。下次一定要认真领会题目的意思。

这样的话暴力解法也不难理解,就是算出每一个i为起点的子序列的长度取最小即可。

滑动窗口法。这个名字一听就很牛逼,但是感觉和之前的快慢指针有异曲同工之妙。

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int result = INT32_MAX; // 最终的结果
        int sum = 0; // 子序列的数值之和
        int subLength = 0; // 子序列的长度
        int i = 0;
        for (int j = 0; j < nums.size(); j++){
            sum += nums[j];
            while (sum >= s){
                subLength = j - i + 1;
                result = subLength < result ? subLength :result;
                sum -= nums[i++];
            }
        }
        return result == INT32_MAX ? 0 : result;
    }
};

原理不难,但是实现的方式也很巧妙。就像一个滑动的窗口一样。利用一个for循环就满足了要求。先让窗口末端延申,延申到一个窗口大小之后,起点前移缩短窗口,然后再终点后移,一直保持着一个刚刚好的窗口大小遍历完所有的子数组,最后利用异或只保留最小的子数组长度即可。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值