A:水题。
解法1:首先确定一个全为1的串,之后如果在出现1,就返回false
1 class Solution { 2 public: 3 bool checkOnesSegment(string s) { 4 bool flag=true; 5 int n=s.size(); 6 for(int i=0;i<n;){ 7 if(s[i]=='1'&&flag){ 8 while(s[i]=='1'){ 9 i++; 10 } 11 flag=false; 12 continue; 13 }else if(s[i]=='1'&&!flag) return false; 14 i++; 15 } 16 return true; 17 } 18 };
解法2:直接找到最前面的1和最后面的1,若中间的字符串被0分割开来的话,返回false
1 class Solution { 2 public: 3 bool checkOnesSegment(string s) { 4 int i=0,j=s.size()-1; 5 while(s[i]=='0') i++; 6 while(s[j]=='0') j--; 7 for(int k=i;k<=j;k++) if(s[k]=='0') return false; 8 return true; 9 } 10 };
B:水题。给定一个数组,和一个goal,要求数组和等于goal,可以向数组内插入元素,但是插入元素x满足,abs(x)<limit;
ans=abs(sum-goal+limit-1)/limit ;
1 class Solution { 2 public: 3 int minElements(vector<int>& nums, int limit, int goal) { 4 long long sum=accumulate(nums.begin(),nums.end(),0ll); 5 return (abs(sum-goal)+limit-1)/limit; 6 } 7 };
C:题目很复杂,但是思路比较简单。
给定一张联通图,受限路径定义为从1到n中每一条边的前一个点到n的距离小于后一个点到n的距离的一条路径。
首先求出每一个点到n的最短路(spfa或者dijkstra),然后递推的求出1到n的受限路径数。
f [ i ] 定义为 i 到n的受限路径数,将{dist[i],i}按距离排序,那么每次算f [ i ] 的时候需要保证dis [ i ] < dis [ j ] (j<i),而小于i的点的受限路径数量已经被算出来了。
即f [ i ] 需要用到的值已经被算出来了,即递推关系是一个拓扑图,所以递推方案是可行的。
1 typedef pair<int,int> PII; 2 class Solution { 3 public: 4 const int mod=1e9+7; 5 const int INF=0x3f3f3f3f; 6 vector<vector<PII>> g; 7 vector<int> dis; 8 vector<bool> st; 9 vector<int> f; 10 void spfa(int n,vector<vector<int>>& edges){ 11 g.resize(n+1),dis.resize(n+1,INF),st.resize(n+1); 12 for(auto edge:edges){ 13 int a=edge[0],b=edge[1],c=edge[2]; 14 g[a].push_back({b,c}); 15 g[b].push_back({a,c}); 16 } 17 queue<int> q; 18 dis[n]=0; 19 q.push(n); 20 while(q.size()){ 21 int t=q.front(); 22 q.pop(); 23 st[t]=false; 24 for(auto x:g[t]){ 25 int j=x.first,w=x.second; 26 if(dis[j]>dis[t]+w){ 27 dis[j]=dis[t]+w; 28 if(!st[j]){ 29 q.push(j); 30 st[j]=true; 31 } 32 } 33 } 34 } 35 } 36 37 int get_res(int n){ 38 f.resize(n+1); 39 vector<PII> v; 40 for(int i=1;i<=n;i++) v.push_back({dis[i],i}); 41 sort(v.begin(),v.end()); 42 f[n]=1; 43 for(auto x:v){ 44 int d=x.first,u=x.second; 45 for(auto p:g[u]){ 46 int j=p.first; 47 if(d>dis[j]){ 48 f[u]=(f[u]+f[j])%mod; 49 } 50 } 51 } 52 return f[1]; 53 } 54 55 int countRestrictedPaths(int n, vector<vector<int>>& edges) { 56 spfa(n,edges); 57 return get_res(n); 58 } 59 };
D:给定一个数组和一个k,问保证每个长度为k的区间异或和为0需要改变的数的最小数目。
1 class Solution { 2 public: 3 const int M=1024,INF=1e8; 4 int s[1024]; 5 int minChanges(vector<int>& nums, int k) { 6 int n=nums.size(),m=(n+k-1)/k; 7 vector<vector<int>> f(k+1,vector<int>(M,INF)); 8 f[0][0]=0; 9 int sum=0,minv=INF; 10 for(int i=1;i<=k;i++){ 11 memset(s,0,sizeof s); 12 int len=m; 13 if(n%k && n%k<i) len--; 14 for(int j=0;j<len;j++){ 15 s[nums[j*k+i-1]]++; 16 } 17 int maxv=0; 18 for(int j=0;j<M;j++){ 19 if(s[j]) maxv=max(maxv,s[j]); 20 } 21 sum+=len-maxv,minv=min(minv,maxv); 22 for(int j=0;j<M;j++){ 23 for(int u=0;u<len;u++){ 24 int x=nums[u*k+i-1],cost=len-s[x]; 25 f[i][j]=min(f[i][j],f[i-1][j^x]+cost); 26 } 27 } 28 } 29 return min(sum+minv,f[k][0]); 30 } 31 };