和爲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]});
}
};