題1:輸入一個遞增排序的數組和一個數字S,在數組中查找兩個數,使得他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。
解法1:雙層循環,從前向後掃描,簡單好想,時間複雜度爲O(n^2)
//時間複雜度爲O(n^2)
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
vector<int> vec;
if( array.empty() || array.size() <2)
return vec;
int length = array.size();
for(int i = 0 ;i<length;++i)
{
for(int j = i+1;j<length;++j)
{
if(array[i]+array[j] == sum)
{
vec.push_back(array[i]);
vec.push_back(array[j]);
return vec;
}
}
}
return vec;
}
思路:在數組中選擇兩個數,如果兩個數之和等於S,就是要找的。如果小於S,希望兩數之和再大一點,由於數組是遞增排序的,可以選擇兩個數中較小的數後面的數,因爲後面的數更大一些。如果大於S,我們想要數字之和小一點,可以選擇較大數之前的數,因爲前面的數小一點。根據此思路,可以定義兩個指針,一個指向最前,向後找;另一個指向最後,向前找。
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
vector<int> vec;
if( array.empty() || array.size() <2)
return vec;
vector<int>::iterator begin = array.begin();
vector<int>::iterator end = array.end();
--end;
while(begin < end)
{
if(*begin + *end == sum)
{
vec.push_back(*begin);
vec.push_back(*end);
break;
}
else if(*begin + *end > sum)
--end;
else
++begin;
}
return vec;
}
由於數組是排序的,所以較小數字一定位於較大數字之前,這就是while循環繼續的條件。函數代碼中只有一個while循環,從兩端向中間進行掃描,所以時間複雜度爲O(n)。
要求兩數乘積最小,兩種解法第一次找的的兩個數字必然是乘積最小的,可以進行簡單驗證。
題2:輸入一個正數S,打印所有和爲S的連續正數序列,至少含有兩個數,例如,輸入15,由於1+2+3+4+5 = 4+5+6 = 7+8 =15,所以打印三個序列,1~5,4~6,7~8.
思路:根據上面題目的想法,可以定義兩個變量small,big,small初始化爲1,big初始化爲2.small增加到(1+S)/2,結束。
假設我們以求和爲9爲例,初始化兩個變量後,此時介於small和big之間的序列爲{1,2},和爲3。小於9,則接下來增加big的值big=3,序列爲{1,2,3},和爲6,仍小於9,則繼續增加big的值big=4,此時序列爲{1,2,3,4},和爲10,此時大於9,我們就要刪掉一些數字,於是我們增加small的值small=2,序列變爲{2,3,4},和爲9,此時我們找到了第一組序列。
接下來我們再增加big的值big=5,序列變爲{2,3,4,5},和爲14,大於9,則增加small的值small=3,序列變爲{3,4,5},和爲12,大於9,則增加small的值small=4,序列變爲{4,5},和爲9,這是第二組序列。
接下來我們增加big的值big=6,序列變爲{4,5,6},和爲15,大於9,則增加small的值small=5,此時small=5 >= (1+S)/2=5,結束。
vector<int> InsertData(int start,int end)
{
vector<int> vec;
for(int i = start;i<=end;++i)
{
vec.push_back(i);
}
return vec;
}
vector<vector<int> > FindContinuousSequence(int sum) {
vector<vector<int>> res;
if(sum <3)
return res;
vector<int> vec;
int middle = (sum+1)/2;
int small = 1;
int big =2;
int cursum = small + big;
while(small < middle)
{
if(cursum == sum)
{
vec = InsertData(small,big);
res.push_back(vec);
}
while(cursum > sum && small < middle)
{
cursum -= small;
++small;
if(cursum == sum)
{
vec = InsertData(small,big);
res.push_back(vec);
}
}
++big;
cursum += big;
}
return res;
}