1000.函数求值
定义超级和函数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
class Solution {
public:
int F(int k, int n) {
int f[k+1][n+1];
memset(f,0,sizeof(f));
for (int i = 0; i <= n; ++i)
{
f[0][i]=i;
}
for (int i = 1; i <= k; ++i)
{
for (int j = 1; j <= n; ++j)
{
for (int l = 1; l <= j; ++l)
{
f[i][j]+=f[i-1][l];
}
}
}
return f[k][n];
}
};
1001.会议安排 贪心
N个会议要同时举行,参会人数分别为A[0], A[1], ..., A[N-1]. 现有M个会议室,会议室可容纳人数分别为B[0], B[1], ..., B[M-1]. 当A[i]<=B[j]时,可以把会议i安排在会议室j,每间会议室最多安排一个会议,每个会议最多只能安排一个会议室. 求最多安排多少个会议.
1 <= N, M <= 100000, 每个会议的参会人数和每间会议室的容纳人数均在1和1000之间.
请为下面的Solution类实现解决上述问题的函数assignConferenceRoom. 函数参数A和B的意义如上,返回值为最多可安排的会议数.
class Solution {
public:
int assignConferenceRoom(vector<int>& A, vector<int>& B) {
}
};
例1:A={2, 3}, B={1, 2},答案为1.
例2:A={3, 4, 5},B={10, 3, 2},答案为2.
class Solution {
public:
int assignConferenceRoom(vector<int>& A, vector<int>& B) {
int n = A.size(),m = B.size();
sort(A.begin(), A.end());
sort(B.begin(), B.end());
int i=0,j=0;
int count=0;
while(i<n&&j<m){
if(A[i]<=B[j]){
count++;
i++;
j++;
}
else{
j++;
}
}
return count;
}
};
1002.等价二叉树
两个二叉树结构相同,且对应结点的值相同,我们称这两个二叉树等价.
例如:以下两个二叉树等价
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) {
}
};
class Solution {
public:
bool isEqual(TreeNode* p, TreeNode* q) {
if(p==NULL && q!=NULL)return false;
if(p==NULL && q==NULL)return true;
if(p!=NULL && q==NULL)return false;
if(p->val == q->val){
return (isEqual(p->left,q->left) && isEqual(p->right,q->right));
}
else{
return false;
}
}
};
1003。相连的1
对于一个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.
class Solution {
public:
int countConnectedOnes(vector<vector<char>>& A) {
int count=0;
int n = A.size();
if(A[0].size()==0)return 0;
int m = A[0].size();
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
if(A[i][j]=='1'){
count++;
wipe(i,j,A);
}
}
}
return count;
}
private:
void wipe(int i,int j,vector<vector<char>>& A){
if(A[i][j]=='1'){
A[i][j]=0;
int n = A.size();
int m = A[0].size();
if(i>0)wipe(i-1,j,A);
if(i<n-1)wipe(i+1,j,A);
if(j>0)wipe(i,j-1,A);
if(j<m-1)wipe(i,j+1,A);
}
else return;
}
};
在图论中,如果一个有向图从任意顶点出发无法经过若干条边回到该点,则这个图是一个有向无环图(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.
//!!!!!超时了
class Solution {
public:
bool isDAG(int n, vector<pair<int, int>>& edges) {
//int degree[n];
map<int,int> degree;
//memset(degree,0,sizeof(degree));
for (int i = 0; i < n; ++i)
{
degree[i]=0;
}
unordered_map<int, vector<int>> graph;
for (std::vector<pair<int, int>>::iterator i = edges.begin(); i != edges.end(); ++i)
{
graph[i->first].push_back(i->second);
degree[i->second]++;
}
int mark;
while((mark=nopre(degree,n))!=-1){
for (int i = 0; i < graph[mark].size(); ++i)
{
degree[graph[mark][i]]--;
}
graph[mark].clear();
std::map<int, int>::iterator it = degree.find(mark);
degree.erase(it);
}
/*for (int i = 0; i < n; ++i)
{
if(degree[i]>0)
return false;
}*/
for (std::map<int,int>::iterator i = degree.begin(); i != degree.end(); ++i)
{
if(i->second>0){
return i->first;
}
}
return true;
}
private:
int nopre(map<int,int> °ree,int n){
/*for (int i = 0; i < n; ++i)
{
if(degree[i]==0)
return i;
}*/
for (std::map<int,int>::iterator i = degree.begin(); i != degree.end(); ++i)
{
if(i->second==0){
return i->first;
}
}
return -1;
}
};
//wang's code
class Solution {
public:
bool isDAG(int n, vector<pair<int, int> >& edges) {
vector<vector<int> > matrix(n);
for(int i = 0; i < edges.size(); i++){
matrix[edges[i].first].push_back(edges[i].second);
}
stack<int> q;
int visit[100000];
for(int i = 0; i < n; i++){
visit[i] = -1;
}
for(int i = 0; i < n; i++){
q.push(i);
visit[i] = 1;
while(!q.empty()){
int d = q.top(), i;
for(i = 0; i < matrix[d].size(); i++){
if(visit[matrix[d][i]] == -1){
q.push(matrix[d][i]);
visit[matrix[d][i]] = 1;
break;
}
if(visit[matrix[d][i]] == 1)return false;
}
if(i == matrix[d].size()){
q.pop(); visit[d] = 0;
}
}
}
return true;
}
};
1005.最大和 动态规划
从数列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.
class Solution {
public:
int maxSum(vector<int>& A) {
int n = A.size();
int f[n];
memset(f,0,sizeof(f));
f[0]=A[0];
if(n>1){
f[1]= max(A[0],A[1]);
}
//f[n] = max(f[n-1],f[n-2]+A[n])
for (int i = 2; i < n; ++i)
{
f[i] = max(f[i-1],f[i-2]+A[i]);
}
return f[n-1];
}
};
1006单词变换 动态规划
对于两个只含有小写英文字母(’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.
class Solution {
public:
int minDistance(string word1, string word2) {
if(word1==word2)return 0;
int m = word1.size(), n = word2.size();
if(m==1&&n==1)return !(word2 == word1);
int e[m+1][n+1];
for (int i = 0; i <= m; ++i)
{
e[i][0]=i;
}
for (int i = 0; i <= n; ++i)
{
e[0][i] = i;
}
for (int i = 1; i <= m; ++i)
{
for (int j = 1; j <= n; ++j)
{
e[i][j] = min( min(e[i-1][j]+1,e[i][j-1]+1) ,
e[i-1][j-1]+diff(word1[i-1],word2[j-1]) );
}
}
return e[m][n];
}
private:
int diff(char i, char j){
if(i==j){
return 0;
}
return 1;
}
};