题解 | #计算数组的小和#

计算数组的小和

https://www.nowcoder.com/practice/6dca0ebd48f94b4296fc11949e3a91b8

#include <vector>
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型vector 
     * @return long长整型
     */
    long long Merge(vector<int>& nums,int l,int mid,int r,vector<int> &refArr)
    {    
        long long  ans=0;
        // for(int i=mid+1;i<=r;i++)
        // {
        //    int res=0;
        //    int j=l;
        //    while(j<=mid&&nums[j]<=nums[i])
        //    {
        //      res+=nums[j++];
        //    }
        //    ans+=res;
        // }   
        int lpos=l;
        int rpos=mid+1;
        int i=l;
        while(lpos<=mid&&rpos<=r)
        {
            //2 6 7 7 | 4 5 6 9
            //(r-rpos+1)*nums[lpos]
            //如果2<4 那么4后面的所有数都比2大,直接用比2大的个数乘以2,就是这一轮比较里面2所能贡献的小和。
            ans+=nums[lpos]<=nums[rpos]?(r-rpos+1)*nums[lpos]:0;
            refArr[i++]=nums[lpos]<=nums[rpos]?nums[lpos++]:nums[rpos++];
        }
        while(lpos<=mid)
        {
            refArr[i++]=nums[lpos++];
        }
        while(rpos<=r)
        {
            refArr[i++]=nums[rpos++];
        }
        for(int j=l;j<=r;j++)
        {
            nums[j]=refArr[j];
        }
        return ans;
    }

    long long smallSum(vector<int> &nums,int l,int r,vector<int> &refArr)
    {
        if(l==r) return 0;
        int mid=l+(r-l)/2;
        //左区间+右区间+左跨右区间
        return smallSum(nums,l,mid,refArr)+smallSum(nums,mid+1,r,refArr)+Merge(nums,l,mid,r,refArr);
    }

    long long calArray(vector<int>& nums) {
        // write code here
        vector<int> refArr(nums.size()+1);//辅助数组
        return smallSum(nums,0,nums.size()-1,refArr);
    }
};

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务