Leetcode 523

来源:互联网 发布:js实现九九乘法表 编辑:程序博客网 时间:2024/05/20 18:55

题意

给一个由非负正数组成的数组和一个数k,要求在数组中找一段长度2的序列使其和是k的整数倍。

思路

算法1

O(n2)时间,O(n)空间

维护数组的前缀和s,对于当前si,遍历si之间是否存在一个sj满足(sisj)%k=0k0

注意k=0的情况。

算法2

如果要求和刚好为k的话,我们对于当前和si,只需要知道之前是否存在sj=sik即可,于是可以用unordered_mapO(1)的去查找。

既然是k的整数倍,我们可以利用%的性质:

x%p=a等价于x=pn+a(1)

y%p=a等价于y=pm+a(2)

(2)(1)相减既有:yx=p(mn),即yxp的整数倍。

所以,我们不维护前缀和而是前缀和%k之后的值x,并且用map保存每个x出现的最早位置,当再次出现x的时候,并且长度大于1,那么就是我们的结果。

代码

algorithm 1

class Solution {public:    bool checkSubarraySum(vector<int>& nums, int k) {        vector<int> sum(nums.size(), 0);        if (nums.size()) {            for (int i = 0; i < nums.size(); i++) sum[i] = (i ? sum[i - 1] : 0) + nums[i];            for (int i = 0; i < nums.size(); i++) {                if (k == 0) {                    if (i && sum[i] == 0) return true;                } else {                    if (sum[i] % k == 0 && i) return true;                }                for (int j = 0; j < i - 1; j++) {                    int x = sum[i] - sum[j];                    if (k == 0) {                        if (x == 0) return true;                    } else {                        if (x % k == 0) return true;                    }                }            }        }        return false;    }};

algorithm 2

class Solution {public:    bool checkSubarraySum(vector<int>& nums, int k) {        unordered_map<int, int> pos;        if (nums.size()) {            int sum = 0; pos[0] = -1;            for (int i = 0; i < nums.size(); i++) {                sum += nums[i];                if (k) sum %= k;                if (pos.count(sum)) {                    int x = pos[sum];                    if (i - x > 1) return true;                } else {                    pos[sum] = i;                    }            }        }        return false;    }};
0 0
原创粉丝点击