算法

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;
	}
};



1004.无环图

在图论中,如果一个有向图从任意顶点出发无法经过若干条边回到该点,则这个图是一个有向无环图(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;
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值