zoukankan      html  css  js  c++  java
  • 【剑指Offer】面试题57

    题目

    输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
    序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

    示例 1:

    输入:target = 9
    输出:[[2,3,4],[4,5]]
    

    示例 2:

    输入:target = 15
    输出:[[1,2,3,4,5],[4,5,6],[7,8]]
    

    限制:
    1 <= target <= 10^5

    思路一:暴力

    从 1 到 target/2,以每个数为开始检查是否存在连续和为 target。

    代码

    时间复杂度:O(n^2)
    空间复杂度:O(1)

    class Solution {
    public:
        vector<vector<int>> findContinuousSequence(int target) {
            vector<vector<int>> res;
            for (int i = 1; i <= target / 2; ++i) {
                vector<int> tmp;
                int sum = i;
                tmp.push_back(i);
                for (int j = i + 1; j <= target / 2 + 1; ++j) {
                    sum += j;
                    tmp.push_back(j);
                    if (sum == target) {                    
                        res.push_back(tmp);
                        break;
                    } else if (sum > target) {
                        break;
                    }
                }            
            }
            return res;
        }
    };
    

    简化代码

    延迟临时数组保存,找到满足条件的数组再保存。

    class Solution {
    public:
        vector<vector<int>> findContinuousSequence(int target) {
            vector<vector<int>> res;
            for (int i = 1; i <= target / 2; ++i) {            
                int sum = i;            
                for (int j = i + 1; j <= target / 2 + 1; ++j) {
                    sum += j;                
                    if (sum == target) {                    
                        vector<int> tmp;
                        for (int k = i; k <= j; ++k) tmp.push_back(k);
                        res.push_back(tmp);
                        break;
                    } else if (sum > target) {
                        break;
                    }
                }            
            }
            return res;
        }
    };
    

    思路二:滑动窗口(双指针)

    设置双指针 l 和 r,初始值分别从1 和 2 开始,通过数学方法计算sum值,然后sum值和target大小关系分下面三种情况讨论:

    • sum == target:找到满足条件的[l, r],加入结果集;
    • sum < target:则移动右指针
    • sum > target:则移动左指针

    终止条件为 l >= r,这种情况只有当r 移到 target / 2 + 1位置时,导致l < r 的时候区间大于target,移动l 使两者相等。

    代码

    时间复杂度:O(n)
    空间复杂度:O(1)

    class Solution {
    public:
        vector<vector<int>> findContinuousSequence(int target) {
            vector<vector<int>> res;
            int l = 1, r = 2;
            while (l < r) {
                int sum = (l + r) * (r - l + 1) / 2;
                if (sum == target) {
                    vector<int> tmp;
                    for (int i = l; i <= r; ++i) tmp.push_back(i);
                    res.push_back(tmp);
                    ++l;
                } else if (sum < target) {
                    ++r;
                } else {
                    ++l;
                }
            }
            return res;
        }
    };
    
  • 相关阅读:
    ElasticSearch6学习(1)-安装Elasticsearch
    Ubuntu 18.04 安装java8
    windows10 php7安装mongodb 扩展
    https加密解密过程详解
    Beanstalkd,zeromq,rabbitmq的区别
    PHP中的++和--
    win10 git bash 闪退
    谈下WebSocket介绍,与Socket的区别
    Bridge桥接模式(结构型模式)
    Apater适配器模式(结构型模式)
  • 原文地址:https://www.cnblogs.com/galaxy-hao/p/12431322.html
Copyright © 2011-2022 走看看