算法和數據結構面試題
1.求子數組的最大和
例如輸入的數組為1, -2, 3, 10, -4, 7, 2, -5,和最大的子數組為3, 10, -4, 7, 2,因此輸出為該子數組的和18。
因為是O(N)的復雜度,因此需采用的DP的思想,記錄下當前元素之和(為其最優狀態,既最大),將其與目前所得的最大和比較,若大於則更新,否則繼續。狀態的累加遵循這個過程:如果當前和小於0,則放棄該狀態,將其歸零。
//求子數組的最大和
//利用的是dp的思想,依次遍歷數組中的每個元素,把他們相加,如果加起來小於0,則
//把當前元素之和清為0,否則則和最大和比較,更新最大和,最後得到必是子數組的最大和
#include<iostream>
using namespace std;
int findGreatestSubSum(const int a[],const int size){
int curSum=0;
int maxSum=0;
for(int i=0;i<size;i++){
curSum+=a[i];
if(curSum<0) curSum=0; //放棄這個階段,從新開始
if(curSum>maxSum) maxSum=curSum; //更新最大和
}
if(maxSum==0){ //若是數組中的元素均為負數,則輸出裏面的最大元素
maxSum=a[0]; //當然這步也可以寫到上面一個循環裏
for(int i=1;i<size;i++){
if(maxSum<a[i]) maxSum=a[i];
}
}
return maxSum;
}
int main(void){
int a[10]={1, -2, 3, 10, -4, 7, 2, -5};
cout<<findGreatestSubSum(a,10)<<endl;
system("pause");
return 0;
}
把金條分成三段(就是分兩次,或者切兩刀),分別是整根金條的1/7、2/7 4/7 第一天:給1/7的, 第二天:給2/7的,收回1/7的 第三天,給1/7的 第四天:給4/7的,收回1/7和2/7的 第五天:給1/7的 第六天:給2/7的,收回1/7的
第3題 翻轉句子中單詞的順序。 題目:輸入一個英文句子,翻轉句子中單詞的順序,但單詞內字符的順序不變。 句子中單詞以空格符隔開。為簡單起見,標點符號和普通字母一樣處理。 例如輸入“I am a student.”,則輸出“student. a am I”。
/*
第 3 題(字符串)
翻轉句子中單詞的順序。
題目:輸入一個英文句子,翻轉句子中單詞的順序,但單詞內字符的順序不變。
句子中單詞以空格符隔開。為簡單起見,標點符號和普通字母一樣處理。
例如輸入“I am a student.”,則輸出“student. a am I”。
start time 15:12
end time 15:39
*/
#include <iostream>
#include <vector>
using namespace std;
typedef struct Words{
int len;
char * start;
}Words;
void reverseSentence(char * c)
{
vector<Words> S; //存儲單詞的棧
Words w;
w.start = c;
w.len = 0;
for (int i = 0; c[i] != ‘\0‘; i++)
{
if (c[i] != ‘ ‘)
{
w.len++;
}
else
{
if (w.len != 0)
{
S.push_back(w);
w.start = c + i + 1;
w.len = 0;
}
else //跳過多余的空格
{
w.start = c + i + 1;
}
}
}
if (w.len != 0) //壓入最後一個詞
{
S.push_back(w);
}
while (!S.empty())
{
Words w = S.back();
for (int i = 0; i < w.len; i++)
{
cout << *(w.start + i);
}
cout << ‘ ‘;
S.pop_back();
}
cout << endl;
}
int main()
{
char * c = " I am a student.";
reverseSentence(c);
return 0;
}
4:求1+2+…+n, 要求不能使用乘除法、for、while、if、else、switch、case等關鍵字以及條件判斷語句(A?B:C)。
分析:這題本來很簡單,但是不能用循環和條件判斷語句。但是理論上所有的遞歸都可以轉化為循環,那是否可以用遞歸代替循環呢?照著這個思路走下去,貌似可以。可是用遞歸的話,遞歸怎麽終止呢?這就得在return語句中做文章了。最讓人奔潰的是不讓用乘除法。但是乘法本質上是加法的累加。
思路:
- 把循環化為遞歸。
- 乘法改為遞歸實現的累加。
- 遞歸的終止靠return語句做文章。
我最終的答案如下(包括測試程序):
- #include <stdio.h>
- int sum = 0;
- _Bool summation(int n)
- {
- sum += n;
- return n-1 && summation(n-1);
- }
- int main()
- {
- int n;
- scanf("%d",&n);
- summation(n);
- printf("%d\n",sum);
- return 0;
- }
算法和數據結構面試題