对于一个01矩阵A,求其中有多少片连成一片的1. 每个1可以和上下左右的1相连.
请为下面的Solution类实现解决这一问题的函数countConnectedOnes,函数参数A为给出的01矩阵,A的行数和列数均不大于1000. 函数的返回值是问题的答案.
例1:
A=
100
010
001
答案为3.
例2:
A=
1101
0101
1110
答案为2.
注意:你只需要提交Solution类的代码,你在本地可以编写main函数测试程序,但不需要提交main函数的代码. 注意不要修改类和函数的名称.
4 分析
该题是DFS的变形应用。
class Solution {
public:
void dfs(vector<vector<char> >& A,int m,int n,int i,int j){
if(i<0 ||j<0 ||i>=m||j>=n)
return;
if(A[i][j]!='1')
return;
else{
A[i][j]='2';
dfs(A,m,n,i-1,j);
dfs(A,m,n,i+1,j);
dfs(A,m,n,i,j+1);
dfs(A,m,n,i,j-1);
}
}
int countConnectedOnes(vector<vector<char> >& A) {
if(A.empty())
return 0;
int m=A.size();
int n=A[0].size();
int count=0;
for(int i=0;ifor(int j=0;jif(A[i][j]=='1'){
count++;
dfs(A,m,n,i,j);
}
return count;
}
};
在图论中,如果一个有向图从任意顶点出发无法经过若干条边回到该点,则这个图是一个有向无环图(Directed Acyclic Graph,DAG). 对于一个n个节点的有向图(节点编号从0到n-1),请判断其是否为有向无环图.
图的节点数和边数均不多于100000.
请为下面的Solution类实现解决上述问题的isDAG函数,函数参数中n为图的节点数,edges是边集,edges[i]表示第i条边从edges[i].first指向edge[i].second. 如果是有向无环图返回true,否则返回false.
例1:
n = 3,edges = {(0, 1), (0, 2)},函数应返回true.
例2:
n = 2,edges = {(0, 1), (1, 0)},函数应返回false.
5 分析
在我看来该题的关键是如何节省时耗。可以用拓扑排序,也可以使用DFS+回溯
5 代码
class Solution {
public:
bool isDAG(int n, vectorint , int> >& edges) {
if(edges.empty())
return true;
stack<int> zeroIn;
vector<int> in(n,0);
vector<set<int> > mp(n);
for(int i=0;ifor(int i=0;iif(in[i]==0)
zeroIn.push(i);
int delNum=0,first;
while(!zeroIn.empty()){
first=zeroIn.top();
zeroIn.pop();
delNum++;
for(set<int>::iterator it = mp[first].begin(); it != mp[first].end(); ++it){
in[*it]--;
if(in[*it]==0)
zeroIn.push(*it);
}
}
if(delNumreturn false;
else
return true;
}
};
从数列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& A) {
}
};
例1:A = {2, 5, 2},答案为5.
例2:A = {2, 5, 4},答案为6.
6 分析
又是一个贪心的应用。
6 代码
形式1:
class Solution {
public:
int maxSum(vector<int>& A) {
if(A.empty())
return 0;
int curMax,lastMax1,lastMax2;
for(int i=0;iif(i==0){
lastMax2=A[0];
curMax=A[0];
}
else if(i==1){
lastMax1=A[0]>A[1]?A[0]:A[1];
curMax=lastMax1;
}
else{
curMax=lastMax2+A[i]>lastMax1? lastMax2+A[i]:lastMax1;
lastMax2=lastMax1;
lastMax1=curMax;
}
}
return curMax;
}
};
形式2
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];
}
};
对于两个只含有小写英文字母(’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.
7 分析
编辑距离的计算,动态规划的应用。用分治的方法会超时。
7 代码
class Solution {
public:
int minDistance(string word1, string word2) {
int a=word1.size();
int b=word2.size();
vector<vector<int> > c(a+1, vector<int>(b+1));
for(int i=0;ifor(int i=0;i0;
for(int i=a-1;i>=0;i--)
for(int j=b-1;j>=0;j--){
if(word2[j]==word1[i])
c[i][j]=c[i+1][j+1];
else
c[i][j]=minValue(c[i][j+1],c[i+1][j],c[i+1][j+1])+1;
}
return c[0][0];
}
int minValue(int t1,int t2,int t3){
if(t1if(t1return t1;
else
return t3;
}else{
if(t2return t2;
else
return t3;
}
}
};