zoukankan      html  css  js  c++  java
  • [LeetCode 829.] 连续整数求和

    LeetCode 829. 连续整数求和

    其实是一道数学题。把他当作一道待定系数的一元二次方程,然后求其合法整数取值。

    题目描述

    给定一个正整数 N,试求有多少组连续正整数满足所有数字之和为 N?

    示例 1:

    输入: 5
    输出: 2
    解释: 5 = 5 = 2 + 3,共有两组连续整数([5],[2,3])求和后为 5。

    示例 2:

    输入: 9
    输出: 3
    解释: 9 = 9 = 4 + 5 = 2 + 3 + 4

    示例 3:

    输入: 15
    输出: 4
    解释: 15 = 15 = 8 + 7 = 4 + 5 + 6 = 1 + 2 + 3 + 4 + 5

    说明: 1 <= N <= 10 ^ 9

    解题思路

    思路一:双指针

    连续整数和,暴力枚举显然是会超时的,考虑用双指针来降低复杂度。
    然而双指针在遇到 case 53084025 发生了超时。

    双指针代码如下:

    class Solution {
    public:
        int consecutiveNumbersSum(int n) {
            int left = 1;
            int right = 1;
            int64_t sum = 1; // avoid overflow
            int cnt = 0;
            while (right <= n) {
                if (sum == n) {
                    cnt++;
                    sum -= left++;
                    sum += ++right;
                } else if (sum < n) {
                    sum += ++right;
                } else if (sum > n) {
                    sum -= left++;
                }
            }
            return cnt;
        } // TLE
    };
    

    思路二:数学

    既然求和验证会超时,那么有没有办法直接根据结果反推求区间呢?
    有的!
    对于长度为k的区间 [x, x+1, ..., x+k-1] 其区间和 sum = kx + k(k-1)/2。根据此公式,我们已知sum也就是n,然后 x>=1 据此可以推出 k 的取值范围是 1<=k<=(sqrt(1+8n)-1)/2,由此,我们枚举 k 然后验证 x 的合法性即可。

    参考代码

        int consecutiveNumbersSum(int n) {
            // k个连续正整数[x, ..., x+k-1]的求和公式 sum = kx + k(k-1)/2
            // 已知sum,枚举k,验证x即可
            // x>=1,于是 1<=k<=(sqrt(1+8n)-1)/2
            int cnt = 0;
            for (int k = (sqrt(1+8ULL*n)-1)/2; k>=1; k--) { // avoid overflow, case 933320757
                if ((n - k*(k-1)/2) % k == 0) {
                    cnt++;
                }
            }
            return cnt;
        } // AC
    

    中文力扣评论区甚至有人上传了这么一段代码,神了:

    int consecutiveNumbersSum(int N) {
        int res = 0;
        for (int i = 1; N > 0; N -= i++)
            res += (N % i == 0);
        return res;
    }
    
  • 相关阅读:
    移动端兼容性问题解决方案
    h5启动原生APP总结
    前端性能优化
    移动端meta行大全
    CSS3,transform3D立体可拖拽正方体实现原理
    FileReader与FileWriter
    lunix cat tail more等用法
    Scanner用法
    SimpleDateFormat的一些常用用法
    Linux下scp的用法
  • 原文地址:https://www.cnblogs.com/zhcpku/p/15321157.html
Copyright © 2011-2022 走看看