SubarraySumEqualsK

给定一个整数数组和一个整数k,你需要找到所有连续子数列中和为k的子序列总个数。

例:

输入:nums = [1,1,1], k = 2
输出: 2

解法一:

先算出数组的前n项和,放在数组sums中,然后再双层循环遍历数组求出和为k的子序列总个数,代码如下:

    int SubarraySumEqualsK(int[] nums, int k)
    {
        int res = 0;
        int[] sums = new int[nums.Length + 1];
        sums[0] = 0;
        for (int i = 0; i < nums.Length; i++)
        {
            sums[i + 1] = sums[i] + nums[i];
        }
        for (int i = 0; i < nums.Length; i++)
        {
            for (int j = i + 1; j <= nums.Length; j++)
            {
                if (sums[j] - sums[i] == k)
                    res++;
            }
        }
        return res;
    }

在提交的时候因为内存超出没有全部AC。后来看到别人的解法

解法二:

利用Dictionary来存储,key为0到当前元素的和,value为这个和出现的次数。

为什么我们这么做呢?其中的道理是啥呢?假设当前遍历到的数组下标为j,则:

sum[0...j]-sum[0...i-1]=sum[i...j];

看懂了吗?要找到元素之和等于k的子数组,显然在这对应的项是等式右边的那一项(sum[i....j]),我们把第一项看成sum,那么得到第二项(sum[0...i-1])为sum-k,所以我们只需要判断整个的Dictionary中有没有存放sum-k的值就可以,存在的话我们就取出它对应的次数加上即可,接着把当前遍历到j的和存放进去;当然,没有出现的话那我们也得把当前的和添加到map中存好。最后,我们介绍一下初始化的问题,也就是map中和为0的初始值应该是多少?是0吗?不急,我们先看看map中的和为0是啥意思?也就是说sum=k,也就是遍历到当前索引j的时候正好和等于k,所以初值不应该是0而是1,最后得累加到最终的结果result中去。

    int SubarraySumEqualsK2(int[] nums, int k)
    {
        int res = 0;
        int sum = 0;

        //key为nums的0到当前元素和,value为这个和出现的次数
        Dictionary<int, int> map = new Dictionary<int, int>();
        map.Add(0, 1);
        foreach (int num in nums)
        {
            sum += num;
            int temp;
            if (map.TryGetValue(sum - k, out temp))
            {
                res += temp;
            }
            if (map.TryGetValue(sum, out temp))
            {
                map[sum] = temp + 1;
            }
            else
            {
                map.Add(sum, 1);
            }
        }
        return res;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值