6.26打卡:剑指 offer两题:和为S的连续正序序列/和为S的两个数字

和为S的连续正序序列

题目描述

小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

输出描述

输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序

思路

题目说的是连续的正序序列,所以构成了一个等差数列,利用公式sum = (a1+an)*n/2求解

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        // 暴力一下,3ms
        vector<vector<int> > ans;
        // n个连续的数,第一个数为k => S = n(n-1)/2 + nk
        for(int k=1;k<sum;k++){
            vector<int> arr;
//start和end分别代表序列的第一个数和最后一个数,共有(end-start+1)个数。化简可得到代码中的if语句,
            for(int n=1;;n++){
                if(n*(n-1)/2 + n*k > sum){//end肯定要比sum要小
                    break;
                }else if(n*(n-1)/2 + n*k == sum){
                    for(int i=0;i<n;i++){
                        arr.push_back(k+i);
                    }
                }
            }
            if(!arr.empty()){
                ans.push_back(arr);
            }
        }

        return ans;
    }
};

和为S的两个数字

题目描述

输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

输出描述:

对应每个测试案例,输出两个数,小的先输出。

思路
因为数组是有序的,所以可以用双指针,指向数组的首尾,具体步骤如下:
1.初始化:指针i指向数组首, 指针j指向数组尾部
2. 如果arr[i] + arr[j] == sum , 说明是可能解
3. 否则如果arr[i] + arr[j] > sum, 说明和太大,所以--j
4. 否则如果arr[i] + arr[j] < sum, 说明和太小,所以++i

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        if (array.empty()) return vector<int>();
        int tmp = INT_MAX;
        pair<int, int> ret;
        int i = 0, j = array.size();
        while (i < j) {
            //如果存在满足的
            if (array[i] + array[j-1] == sum) {
                if (array[i]*array[j-1] < tmp) {//不能越界
                    tmp = array[i] * array[j-1];
                    ret = {i, j-1};//存进去
                }
                ++i, --j;
            }
            else if (array[i] + array[j-1] < sum) {
                ++i;
            }
            else {
                --j;
            }
        }
        if (ret.first == ret.second) return vector<int>();
        return vector<int>({array[ret.first], array[ret.second]});
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章