题解 | #和为S的连续正数序列# 数学方法O(S),80.14%

和为S的连续正数序列

http://www.nowcoder.com/practice/c451a3fd84b64cb19485dad758a55ebe

(2 * start + n - 1) * n / 2 = sum其中,sum为和,start为首项,n为项数
可以得到2 * sum >= n^2 + n > n^2 所以 n < sqrt(2 * sum)
因此从2(因为至少两项)遍历到sqrt(2*sum)即可

import java.util.*;

public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer> > ans = new ArrayList();
        // (2s+n-1)*n = 2sum >= n^2+n >n^2
        // 所以,n < sqrt(2sum)
        int maxBound = (int)Math.ceil(Math.sqrt(2 * sum));
        // 至少包含两个数,因此n(即i)至少为2
        // n从后向前遍历符合首项从小到大的要求(n越大,首项越小)
        for (int i = maxBound - 1; i >= 2 ; i--) {
            // 查看是否能够整除
            if (2*sum%i!=0) {
                continue;
            }
            if ((2*sum/i+1-i)%2!=0) {
                continue;
            }
            // 找到了满足的列表
            int start = (2*sum/i+1-i)/2;
            ArrayList list = new ArrayList();
            for (int j = 0; j < i; j++) {
                list.add(start+j);
            }
            ans.add(list);
        }
        return ans;
    }
}

为什么不是O(根号S)? 因为最外层虽然是根号S,但是创建res列表时候又遍历了一遍,也是根号S,注意这段代码

            // 找到了满足的列表
            int start = (2*sum/i+1-i)/2;
            ArrayList list = new ArrayList();
            for (int j = 0; j < i; j++) {
                list.add(start+j);
            }
            ans.add(list);
全部评论

相关推荐

点赞 评论 收藏
分享
面试摇了我吧:啊哈哈面试提前五个小时发,点击不能参加就是放弃
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-20 19:57
已编辑
某大厂 golang工程师 23.0k*16.0, 2k房补,年终大概率能拿到
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务