【每日刷题】和相同的二元子数组

day15, 和相同的二元子数组

题目来源:leetcode
在由若干 0 和 1 组成的数组 A 中,有多少个和为 S 的非空子数组。

示例:
输入:A = [1,0,1,0,1], S = 2
输出:4
解释:
如下面黑体所示,有 4 个满足题目要求的子数组:
[1,0,1,0,1]
[1,0,1,0,1]
[1,0,1,0,1]
[1,0,1,0,1]

解答:先说一个O(n^2)的方法,暴力枚举即可。
代码:

class Solution {
public:
    int numSubarraysWithSum(vector& A, int S) {
        int result = 0;
        for( int i = 0; i < A.size(); i++){
            int sum = 0;
            for( int j = i; j < A.size(); j++){
                if( sum + A[j] == S)
                    sum+=A[j], result++;
                else
                    sum+=A[j];
                if( sum > S)
                    break;
            }
        }
        return result;
    }
};

执行结果:?
【每日刷题】和相同的二元子数组_第1张图片

优化:遍历一遍数组,统计每一个满足题意要求的连续序列的两边的0的个数。

代码:

class Solution {
public:
int numSubarraysWithSum(vector<int>& A, int S) {
        int result = 0;
        int i = 0;
    
        //when S = 0
        if( S == 0){
            int sum_zero = 0;
            for( int i = 0; i < A.size(); i++){
                if( A[i] == 0)
                    sum_zero++;
                else{
                    result += (sum_zero + 1) * sum_zero /2;
                    sum_zero = 0;
                }
            }
            result += (sum_zero + 1) * sum_zero /2;
            return result;
        }
    
        while( A[i] == 0 && i < A.size())
            i++;
        while( i < A.size()){
            int sum = 0;
            int j = i;
            for( ; j < A.size(); j++){
                if( sum != S)
                    sum += A[j];
                if( sum == S)
                    break;
            }

            if( sum == S){
           //     cout<<"i = "<int left = 0, right = 0; //左右0的个数
                int i_left = i - 1, j_right = j+1;

                while( i_left >= 0 && A[i_left] == 0)
                    i_left--,left++;

                while( j_right < A.size() && A[j_right] == 0)
                    j_right++, right++;
              //  cout<<"left_0 = "<= result + 1
            + (max( right,left) - min(left,right)) * (min(left,right) + 1)
            + (min(left,right) + 2) * min(left,right);

                    //find next 1
                for( i = i + 1; A[i]!=1;i++)
                    ;
            }
            else if( sum != S)
                break;
            
            if( j == A.size() - 1 || i == A.size() - 1)
                break;
        }

        return result;
    }
};

运行结果:…还是没有达到O(n)量级。
【每日刷题】和相同的二元子数组_第2张图片


我的微信公众号

在这里插入图片描述

你可能感兴趣的:(每日刷题)