演算法機考模擬題
阿新 • • 發佈:2019-02-04
一、
1、題目描述
Description定義超級和函式F如下:
F(0, n) = n,對於所有的正整數n.. F(k, n) = F(k – 1, 1) + F(k – 1, 2) + … + F(k – 1, n),對於所有的正整數k和n. 請實現下面Solution類中計算F(k, n)的函式(1 <= k, n <= 14). class Solution { public: int F(int k, int n) { } }; 例1:F(1, 3) = 6 例2:F(2, 3) = 10 例3:F(10, 10) = 167960 注意:你只需要提交Solution類的程式碼,你在本地可以編寫main函式測試程式,但不需要提交main函式的程式碼. 注意不要修改類和函式的名稱.2、考點及思路
考查分治思想,將一個大問題劃分為一個小問題,並通過遞迴的方式完成小問題。
3、程式碼實現
class Solution {
public:
int F(int k, int n) {
if(k==0) return n;
else{
int sum=0;
for(int i=1;i<=n;i++){
sum+=F(k-1,i);
}
return sum;
}
}
};
二、
1、題目描述
2、考點及思路
考查貪心演算法,將兩個陣列排序,並用最大會議室去滿足最大需求,無法滿足則看次之的需求。
3、程式碼實現
class Solution {
public:
int assignConferenceRoom(vector<int>& A, vector<int>& B) {
sort(A.begin(),A.end());
sort(B.begin(),B.end());
int a=A.size()-1;
int b=B.size()-1;
int count=0;
while(a>=0&&b>=0){
if(B[b]<A[a]){
a--;
}
else{
b--;
a--;
count++;
}
}
return count;
}
};
三、
1、題目描述
Description 兩個二叉樹結構相同,且對應結點的值相同,我們稱這兩個二叉樹等價. 例如:以下兩個二叉樹等價 1 1 / \ / \ 2 3 2 3 而以下兩個則不等價 1 1 / \ / \ 2 3 3 2 以下兩個也不等價 1 1 / \ / \ 2 3 2 2 給出兩個二叉樹p和q,判斷它們是否等價. p和q的結點數不多於100000,每個結點的數值在1和1000000000之間. 請為下面的Solution類實現解決上述問題的isEqual函式,函式的兩個引數p和q分別代表兩個二叉樹的根節點,如果以p和q為根的二叉樹等價則函式返回true,否則返回false. /** Definition for a binary tree node. struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; */ class Solution { public: bool isEqual(TreeNode* p, TreeNode* q) { } }; 注意:你只需要提交Solution類的程式碼,你在本地可以編寫main函式測試程式,但不需要提交main函式的程式碼,也不需要提交TreeNode的定義. 注意不要修改類和函式的名稱.2、考點及思路
考查DFS,通過DFS搜尋兩棵樹,對比檢視是否相同,我使用的是遞迴實現版本。
3、程式碼實現
class Solution {
public:
bool isEqual(TreeNode* p, TreeNode* q) {
if(p==NULL&&q==NULL)
return true;
if((p==NULL&&q!=NULL)||(q==NULL&&p!=NULL))
return false;
if(p->val!=q->val)
return false;
else
return (isEqual(p->left,q->left)&&isEqual(p->right,q->right));
}
};
四、
1、題目描述
Description 對於一個01矩陣A,求其中有多少片連成一片的1. 每個1可以和上下左右的1相連. 請為下面的Solution類實現解決這一問題的函式countConnectedOnes,函式引數A為給出的01矩陣,A的行數和列數均不大於1000. 函式的返回值是問題的答案. class Solution { public: int countConnectedOnes(vector<vector<char>>& A) { } }; 例1: A= 100 010 001 答案為3. 例2: A= 1101 0101 1110 答案為2. 注意:你只需要提交Solution類的程式碼,你在本地可以編寫main函式測試程式,但不需要提交main函式的程式碼. 注意不要修改類和函式的名稱.2、考點及思路
考查BFS,通過BFS尋找一個點所連線的所有點,我使用queue記錄同一層的節點。
3、程式碼實現
class Solution {
public:
int countConnectedOnes(vector<vector<char>>& A) {
int m = A.size();
if (m == 0) return 0;
int n = A[0].size();
if (n == 0) return 0;
vector<vector<bool>> B(m, vector<bool>(n, false));
int count = 0;
for (int i = 0; i<m; i++) {
for (int j = 0; j<n; j++) {
if (A[i][j] == '1'&&B[i][j] == false) {
count++;
BFS(A, B, i, j);
}
}
}
return count;
}
void BFS(vector<vector<char>>& A, vector<vector<bool>>& B, int i, int j) {
queue<pair<int, int>> que;
que.push(make_pair(i, j));
while (!que.empty()) {
pair<int, int> p = que.front();
que.pop();
if (p.first -1 >= 0 && A[p.first -1][p.second] == '1'&&B[p.first - 1][p.second] == false) {
que.push(make_pair(p.first - 1, p.second));
B[p.first - 1][p.second] = true;
}
if (p.first + 1 <A.size() && A[p.first + 1][p.second] == '1'&&B[p.first + 1][p.second] == false) {
que.push(make_pair(p.first + 1, p.second));
B[p.first + 1][p.second] = true;
}
if (p.second - 1 >= 0 && A[p.first][p.second-1] == '1'&&B[p.first][p.second-1] == false) {
que.push(make_pair(p.first, p.second-1));
B[p.first][p.second-1] = true;
}
if (p.second + 1 < A[0].size() && A[p.first][p.second + 1] == '1'&&B[p.first][p.second + 1] == false) {
que.push(make_pair(p.first, p.second + 1));
B[p.first][p.second + 1] = true;
}
}
}
};
五、
1、題目描述
Description 在圖論中,如果一個有向圖從任意頂點出發無法經過若干條邊回到該點,則這個圖是一個有向無環圖(Directed Acyclic Graph,DAG). 對於一個n個節點的有向圖(節點編號從0到n-1),請判斷其是否為有向無環圖. 圖的節點數和邊數均不多於100000. 請為下面的Solution類實現解決上述問題的isDAG函式,函式引數中n為圖的節點數,edges是邊集,edges[i]表示第i條邊從edges[i].first指向edge[i].second. 如果是有向無環圖返回true,否則返回false. class Solution { public: bool isDAG(int n, vector<pair<int, int>>& edges) { } }; 例1: n = 3,edges = {(0, 1), (0, 2)},函式應返回true. 例2: n = 2,edges = {(0, 1), (1, 0)},函式應返回false. 注意:你只需要提交Solution類的程式碼,你在本地可以編寫main函式測試程式,但不需要提交main函式的程式碼. 注意不要修改類和函式的名稱.2、考點及思路
考查圖論知識,我在檢查是否有回邊的過程中使用了dfs進行檢索。
3、程式碼實現
class Solution {
public:
bool isDAG(int n, vector<pair<int, int>>& edges) {
vector<vector<int>> graph(n);
for (int i = 0; i < edges.size(); i++)
graph[edges[i].first].push_back(edges[i].second);
vector<bool> visited(n, false);
vector<bool> onpath(n,false);
for (int i = 0; i < n; i++)
if (has_circle(graph,i,visited,onpath))
return false;
return true;
}
bool has_circle(vector<vector<int>>& graph, int node, vector<bool>& visited, vector<bool>& onpath) {
if (visited[node]) return false;
onpath[node] = visited[node] = true;
for (int i = 0; i < graph[node].size(); i++) {
if (onpath[graph[node][i]] || has_circle(graph, graph[node][i], visited, onpath))
return true;
}
onpath[node] = false;
return false;
}
};
六、
1、題目描述
Description 從數列A[0], A[1], A[2], ..., A[N-1]中選若干個數,要求相鄰的數不能都選,也就是說如果選了A[i], 就不能選A[i-1]和A[i+1]. 求能選出的最大和. 1 <= N <= 100000, 1 <= A[i] <= 1000 請為下面的Solution類實現解決上述問題的函式maxSum,函式引數A是給出的數列,返回值為所求的最大和. class Solution { public: int maxSum(vector<int>& A) { } }; 例1:A = {2, 5, 2},答案為5. 例2:A = {2, 5, 4},答案為6. 注意:你只需要提交Solution類的程式碼,你在本地可以編寫main函式測試程式,但不需要提交main函式的程式碼. 注意不要修改類和函式的名稱.2、考點及思路
考查動態規劃,定義函式並寫出狀態轉移方程即可。
3、程式碼實現
class Solution {
public:
int maxSum(vector<int>& A) {
if (A.size() == 0) return 0;
vector<int> f(A.size());
f[0] = A[0];
f[1] = A[0] > A[1] ? A[0] : A[1];
for (int i = 2; i < A.size(); i++) {
f[i] = f[i - 1] > (f[i - 2] + A[i]) ? f[i - 1] : (f[i - 2] + A[i]);
}
return f[A.size() - 1];
}
};
七、
1、題目描述
Description 對於兩個只含有小寫英文字母(’a’-‘z’)的單詞word1和word2,你可以對word1進行以下3種操作: 1) 插入一個字母; 2) 刪除一個字母; 3) 替換一個字母. 請計算將word1變換成word2的最少運算元. word1和word2的長度均不大於1000. 請為下面的Solution類實現解決上述問題的函式minDistance,函式的引數word1和word2為給出的兩個單詞,返回值為所求最少運算元. class Solution { public: int minDistance(string word1, string word2) { } }; 例1:word1 = “sunny”, word2 = “snowy”,返回值為3. 例2:word1 = “abc”, word2 = “ac”,返回值為1. 注意:你只需要提交Solution類的程式碼,你在本地可以編寫main函式測試程式,但不需要提交main函式的程式碼. 注意不要修改類和函式的名稱.2、考點及思路
考查動態規劃。需要注意dp[i][j]表示長度為i的word1與長度為j的word2的單詞距離,dp的兩個維度的長度分別為m+1,n+1,同時dp[i][j]對應的最後一個字元是字串word1[i-1]和word2[j-1]。
3、程式碼實現
class Solution {
public:
int minDistance(string word1, string word2) {
int x= word1.length();
int y= word2.length();
vector<vector<int>> dp(x+1,vector<int>(y+1,0));
for(int i=0;i<=x;i++){
dp[i][0]=i;
}
for(int j=0;j<=y;j++){
dp[0][j]=j;
}
for(int i=1;i<=x;i++){
for(int j=1;j<=y;j++){
if(word1[i-1]==word2[j-1])
dp[i][j]=dp[i-1][j-1];
else{
dp[i][j]=min(dp[i-1][j-1],min(dp[i][j-1],dp[i-1][j]))+1;
}
}
}
return dp[x][y];
}
};