leetcode560-和为k的子数组(c++/python)

题目

在这里插入图片描述

思路

题目要求解连续子数组的和等于k的个数,首先得明确如何求解连续子数组的和?

可以利用前缀和数组来实现任意两个位置连续的子数组的和!

前缀和数组的含义如下:

如下图所示,假设数组nums的长度为n,则前缀和数组presums的长度为n+1,对于任意位置i,presums[i]=presums[i-1]+nums[i]=nums[0]+…+nums[i-1],一般设定前缀和数组的第一个元素为0。

有了前缀和数组作为辅助数组,那么求解任意任意两个位置的连续的子数组的和就可转换为:nums[i]+…+nums[j]=presums[j+1]-presums[i],时间复杂度只有o(1)。
在这里插入图片描述
有了前缀和数组,如何求解本题呢?

  • 思路1:i遍历前缀和数组,用j遍历i的前驱区域[0,i-1) ,寻找nums[i]-nums[j]=k的j的数目。

    但这种方式最坏情况需要遍历两次数组,时间复杂度为o(n2)。

  • 思路2:这里可以参考 leetcode.1 two sum的解法。利用哈希表存储前缀和数组的元素以及出现的次数,对于nums[i]-k,如果哈希表中存在,则直接累加其次数;如果不存在,则将nums[i]元素插入哈希表,需要注意的是,需要判定哈希表中是否存在nums[i]。

    由于哈希表查找的时间复杂度为o(1),外循环的时间复杂度为o(n),因此该方法的时间复杂度为o(n)。

题解

思路1

C++

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        if(nums.empty()) return 0;
        int n=nums.size();
        vector<int> ans(n+1);
        ans.push_back(0);
        for(int i=0;i<n;i++) ans[i+1]=ans[i]+nums[i];
        int res=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<i;j++)
            {
                if(ans[i]-ans[j]==k) res++;
            }
        }
        return res;
    }
};

C++勉强通过!!!
在这里插入图片描述
Python

直接超时

class Solution(object):
    def subarraySum(self, nums, k):
        if not nums: return 0 
        n=len(nums)
        ans=[0]*(n+1)
        for i in range(n):  ans[i+1]=ans[i]+nums[i]  
        res=0
        for m in range(1,n+1):
            for n in range(0,m):
                if(ans[m]-ans[n]==k):
                    res+=1
        return res

思路2

C++

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        
        if(nums.empty()) return 0;
        unordered_map<int,int>ans;
        ans[0]=1;
        
        int sum_i=0,sum_j=0,res=0;
        for(int i=0;i<nums.size();i++)
        {
            sum_i+=nums[i];
            
            sum_j=sum_i-k;
            
            if(ans.count(sum_j))
            {
                res+=ans[sum_j];
            }
            ans[sum_i]++;
        }
        return res;
    }
};

在这里插入图片描述
Python:

class Solution(object):
    def subarraySum(self, nums, k):
        if not nums: return 0 
        res={}
        res[0]=1
        sum_i,sum_j,ans=0,0,0
        for i in range(len(nums)):
            sum_i+=nums[i]
            sum_j=sum_i-k
            if(sum_j in res):
                ans+=res[sum_j]
            if sum_i not in res:
                res[sum_i]=0
            res[sum_i]+=1
        return ans
            

果然python慢点哈!
在这里插入图片描述

参考

1.https://leetcode-cn.com/problems/subarray-sum-equals-k/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值