LeetCode 171周赛题解
Posted zb121
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 171周赛题解相关的知识,希望对你有一定的参考价值。
1317. 将整数转换为两个无零整数的和
1 class Solution { 2 public: 3 bool check(int n){ 4 while(n){ 5 if(n%10==0){ 6 return false; 7 } 8 n=n/10; 9 } 10 return true; 11 } 12 vector<int> getNoZeroIntegers(int n) { 13 for(int i=1;i<=n;i++){ 14 if(check(i)&&check(n-i))return {i,n-i}; 15 } 16 return {}; 17 } 18 };
1318. 或运算的最小翻转次数
1 class Solution { 2 public: 3 int minFlips(int a, int b, int c) { 4 int cnt=0; 5 while(a>0||b>0||c>0){ 6 int m=a&1,n=b&1,k=c&1; 7 if((m|n)!=k){ 8 if(k==1){ 9 cnt++; 10 //cout<<cnt<<endl; 11 }else{ 12 if(m==1&&n==1)cnt+=2; 13 else cnt++; 14 //cout<<cnt; 15 } 16 } 17 a=a>>1; 18 b=b>>1; 19 c=c>>1; 20 } 21 return cnt; 22 } 23 };
1319. 连通网络的操作次数
解法一:并查集:
1 const int maxn=1e5+10; 2 int father[maxn]; 3 class Solution { 4 public: 5 //是一个图论的问题。。。 6 //首先计算一下连通图的数量,一个连通图的最小边就是机子个数减一,剩下的线如果等于连通图数减一,那么就是符合条件的。。。 7 //如何计算连通图的数量??? 8 int find(int x){ 9 while(father[x]!=x){ 10 x=father[x]; 11 } 12 return x; 13 } 14 void Uni(int a,int b){ 15 int f1=find(a); 16 int f2=find(b); 17 if(f1>f2)swap(f1,f2); 18 father[f2]=f1; 19 } 20 int makeConnected(int n, vector<vector<int>>& connections) { 21 int m=connections.size();//表示的是总共有多少条边; 22 //使用并查集求解连通图的数量. 23 if(m<n-1)return -1; 24 for(int i=0;i<n;i++){ 25 father[i]=i;//初始化 26 } 27 //set<int>cl; 28 for(int i=0;i<m;i++){ 29 int k=connections[i][0],p=connections[i][1]; 30 // cl.insert(k); 31 // cl.insert(p); 32 Uni(k,p); 33 } 34 //int num=cl.size()-1;//表示的是结点数量减一,即所需要的最少边的数量。 35 int cnt=0; 36 for(int i=0;i<n;i++){ 37 if(father[i]==i)cnt++; 38 } 39 return cnt-1;//最小的需要线路是连通图数减一,不需要使用set 40 41 } 42 };
解法二:DFS
1 const int maxn=1e5+10; 2 vector<int>E[maxn]; 3 class Solution { 4 public: 5 //DFS解法,DFS需要注意的是,这个connections图是单向的图,但是DFS需要的是双向的图。。。 6 void dfs(int x,vector<int>&vis){ 7 vis[x]=1; 8 for(int i=0;i<E[x].size();i++){ 9 int v=E[x][i]; 10 if(vis[v]==0){ 11 dfs(v,vis); 12 } 13 } 14 } 15 int makeConnected(int n, vector<vector<int>>& connections) { 16 int m=connections.size(); 17 vector<int>vis(n+1,0);//表示的是初始化为没有访问,初始化为0; 18 int cnt=0;//表示的是总共有多少个连通块。。。 19 if(m<n-1)return -1;//直接返回-1,因为边小于结点数-1,那么无论如何都组不成连通图。。。 20 for(int i=0;i<m;i++){ 21 E[connections[i][0]].push_back(connections[i][1]); 22 E[connections[i][1]].push_back(connections[i][0]); 23 } 24 for(int i=0;i<n;i++){ 25 if(vis[i]==0){ 26 dfs(i,vis); 27 cnt++; 28 } 29 }//这样就求出了连通图的数量。。。 30 return cnt-1; 31 } 32 };
1320. 二指输入的的最小距离
1 int dp[350][27][27];//dp[i][j][k]表示的是在第i个位置上,第一个手指的字符为j,第二个手指的字符为K 2 int n; 3 const int maxn=10086; 4 class Solution { 5 public: 6 //先写一个代价函数,求出相应的代价的. 7 int Cost(int a,int b){ 8 //if(a==26||b==26)return 0; 9 return abs(a/6-b/6)+abs(a%6-b%6); 10 } 11 int minimumDistance(string word) { 12 memset(dp,maxn,sizeof(dp)); 13 n=word.length(); 14 for(int i=0;i<26;i++){ 15 for(int j=0;j<26;j++){ 16 dp[0][i][j]=0;//初始化将第0个位置不放元素这个是为了方便之后的操作。。。方便后面dp操作 17 } 18 } 19 for(int i=1;i<=n;i++){ 20 int m=word[i-1]-‘A‘;//我们都是从阿拉伯数字开始算起的 21 for(int j=0;j<26;j++){ 22 for(int k=0;k<26;k++){ 23 if(dp[i-1][j][k]!=maxn){ 24 dp[i][m][k]=min(dp[i-1][j][k]+Cost(j,m),dp[i][m][k]); 25 dp[i][j][m]=min(dp[i-1][j][k]+Cost(k,m),dp[i][j][m]);//为什么可能是本身. 26 //因为有可能两个单词相同。 27 } 28 } 29 } 30 } 31 int min_num=maxn; 32 for(int i=0;i<26;i++){ 33 for(int j=0;j<26;j++){ 34 if(dp[n][i][j]!=maxn){ 35 min_num=min(min_num,dp[n][i][j]); 36 } 37 } 38 } 39 return min_num; 40 41 } 42 };
以上是关于LeetCode 171周赛题解的主要内容,如果未能解决你的问题,请参考以下文章