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

猜你喜欢

转载自www.cnblogs.com/zb121/p/12416514.html