A:水题,给定两个字符串,问能否只交换一次使得两字符串相等。
解法1:记录两字符串不相等的位置。
1 class Solution { 2 public: 3 bool areAlmostEqual(string s1, string s2) { 4 int n=s1.length(); 5 int cnt=0; 6 int a=-1,b=-1; 7 for(int i=0;i<n;i++){ 8 if(s1[i]!=s2[i]){ 9 cnt++; 10 if(cnt==1) a=i; 11 else if(cnt==2) b=i; 12 } 13 } 14 if(cnt==0||(cnt==2&&s1[a]==s2[b]&&s1[b]==s2[a])){ 15 return true; 16 } 17 return false; 18 } 19 };
解法二:枚举s1所有可能的交换两个位置的情况,判断两字符串是否相等,时间复杂度为O(n^3)
1 class Solution { 2 public: 3 bool areAlmostEqual(string s1, string s2) { 4 if(s1==s2) return true; 5 int n=s1.size(); 6 for(int i=0;i<n;i++){ 7 for(int j=0;j<i;j++){ 8 swap(s1[i],s1[j]); 9 if(s1==s2) return true; 10 swap(s1[i],s1[j]); 11 } 12 } 13 return false; 14 } 15 };
B:给定一个星型图,要你找中心点。
枚举每个节点的度,如果超过1,则是中心点。
1 class Solution { 2 public: 3 int findCenter(vector<vector<int>>& edges) { 4 unordered_map<int,int> d; 5 for(auto &x:edges){ 6 int a=x[0],b=x[1]; 7 if(++d[a]>=2) return a; 8 if(++d[b]>=2) return b; 9 } 10 return -1; 11 } 12 };
C:给定n个班级的不通过的学生和通过的学生
以及n个尖子生。问将尖子生分给各个班级后,最大平均通过率是多少。
( x + 1 ) / ( y + 1 ) - x / y = ( y - x ) / ( y * ( y + 1 ) )
所以若以向某个班级添加的人数为x,增加的通过率为y建立函数的话,该函数是单调递减
而我们希望最大化平均通过率,n是不变的,也就是最大化通过率之和。
那么我们希望每次添加的人的增量是最大的。
这就是典型的多路归并的模型。
1 class Solution { 2 public: 3 double maxAverageRatio(vector<vector<int>>& classes, int k) { 4 struct Node{ 5 double s; 6 int a,b; 7 Node(double _s,int _a,int _b):s(_s),a(_a),b(_b){} 8 bool operator<(const Node& t)const { 9 return s<t.s; 10 } 11 bool operator>(const Node& t)const { 12 return s>t.s; 13 } 14 }; 15 priority_queue<Node,vector<Node>,less<Node>> q; 16 double res=0; 17 for(auto &x:classes){ 18 int a=x[0],b=x[1]; 19 double s=(b-a)/(b*(b+1.0)); 20 res+=a/(b+0.0); 21 q.push({s,a,b}); 22 } 23 while(k--){ 24 Node t=q.top(); 25 q.pop(); 26 res+=t.s; 27 int a=t.a+1,b=t.b+1; 28 double s=(b-a)/(b*(b+1.0)); 29 q.push({s,a,b}); 30 } 31 return res/classes.size(); 32 } 33 };
D:对于每一段答案序列,其中必然有一个或者多个最小的数。
所以如果我们对每一个数都向其两边扩散,必然会将最终答案包括在内。暴力做的复杂度为O(n^2)。
我们可以借助单调栈这个数据结构,对于每一个数,求出大于等于他的左边最远和右边最远,用时O(n),然后就可以直接计算答案了。总时间复杂度为O(n)
1 class Solution { 2 public: 3 int maximumScore(vector<int>& nums, int k) { 4 int n=nums.size(); 5 vector<int> h(n+2,-1),l(n+2),r(n+2),stk(n+2); 6 for(int i=1;i<=n;i++){ 7 h[i]=nums[i-1]; 8 } 9 stk[0]=0; 10 int tt=0; 11 for(int i=1;i<=n;i++){ 12 while(h[stk[tt]]>=h[i]) tt--; 13 l[i]=stk[tt]; 14 stk[++tt]=i; 15 } 16 stk[0]=n+1; 17 tt=0; 18 for(int i=n;i>0;i--){ 19 while(h[stk[tt]]>=h[i]) tt--; 20 r[i]=stk[tt]; 21 stk[++tt]=i; 22 } 23 int res=0; 24 k++; 25 for(int i=1;i<=n;i++){ 26 if(l[i]<k&&r[i]>k){ 27 res=max(res,h[i]*(r[i]-l[i]-1)); 28 } 29 } 30 return res; 31 } 32 };