题解 | #和为S的连续正数序列#

和为S的连续正数序列

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

1 思考

  • 先直接用序列最大和模板套,忽略序列有序,不是求最大和的背景,浪费一半时间
  • 确定双指针思路后,再尝试提交,一半时间在处理边界问题

1.1 没认真读题

  • 和为S的连续正数序列
  • 在想究竟有多少种连续的正数序列的和为100(至少包括两个数)

数字是已经排好序的,第二要求至少2个正数

  • 先算和 ,再比较,可以避免很多细节问题,但是有额外除法的开销(数列求和哈)

坑点

alt

2 code

  • c++ 累计两小时,

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int> > outV;
        vector<int> inV;
        if(sum ==0){
            return outV;
        }
        
        int i = 1 ,j = 0;
        //初始值,累计花了15分钟
        //int localSum = 0, gSum = 0 , start = 0, end = 1;
        int  start = 1, end = 2, localSum = start, gSum = 0 ;
        //for(; i< sum ;i++){
            //累计花了5分钟,查while {}缺失
        while( start <end){
            //参考其他的代码,如果这里 等差数列求和的话,对于边界情况就比较容易处理,但是除法开销。
            if(localSum< sum){
                localSum += end;//end = i;
                end++;
            }else if( localSum == sum){
                //这里面的细节还比较多 //边界值,累计花了5分钟
                if(end-1 == start || sum <=2)
                    break;
                inV.clear();
                //排除边界,累计2分钟,左闭右开
                for(j = start; j<end ;j++) 
                    inV.push_back(j);
                outV.push_back(inV);
                //处理双指针,累计3分钟,add compensate
                localSum -= start;
                start++;
            }else{
                //如果当前窗口内的值之和大于sum,那么左边窗口右移一下
                //而当前的重置,就做不到以上效果,尝试减去start? 然后start也更新哈
                //localSum = i;//start = i;//end = i;
                localSum -= start;
                start++;
            }//else
        }//while //end for
        return outV;
        
    }
};



import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        //存放结果
        ArrayList<ArrayList<Integer> > result = new ArrayList<>();
        //两个起点,相当于动态窗口的两边,根据其窗口内的值的和来确定窗口的位置和大小
        int plow = 1,phigh = 2;
        while(phigh > plow){
            //由于是连续的,差为1的一个序列,那么求和公式是(a0+an)*n/2
            int cur = (phigh + plow) * (phigh - plow + 1) / 2;
            //相等,那么就将窗口范围的所有数添加进结果集
            if(cur == sum){
                ArrayList<Integer> list = new ArrayList<>();
                for(int i=plow;i<=phigh;i++){
                    list.add(i);
                }
                result.add(list);
                plow++;
            //如果当前窗口内的值之和小于sum,那么右边窗口右移一下
            }else if(cur < sum){
                phigh++;
            }else{
            //如果当前窗口内的值之和大于sum,那么左边窗口右移一下
                plow++;
            }
        }
        return result;
    }
}
全部评论

相关推荐

11-24 00:11
已编辑
广东工业大学 算法工程师
避雷深圳&nbsp;&nbsp;yidao,试用期&nbsp;6&nbsp;个月。好嘛,试用期还没结束,就直接告诉你尽快找下一家吧,我谢谢您嘞
牛客75408465号:笑死,直属领导和 hr 口径都没统一,各自说了一些离谱的被裁理由,你们能不能认真一点呀,哈哈哈哈哈😅😅😅
点赞 评论 收藏
分享
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
09-30 19:49
起名星人:蛮离谱的,直接要求转投销售
投递汇川技术等公司10个岗位
点赞 评论 收藏
分享
有趣的牛油果开挂了:最近这个阶段收到些杂七杂八的短信是真的烦
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务