题意:

给你两个字符串 图片说明图片说明 ,字符串由小写字母组成,长度都为4,现在给你一种操作方法,每次操作你可以选择3个位置将其分别 "加上" 2,3,5,即图片说明 ,现在问你 最少操作 几次可以将 图片说明 变成 图片说明

解法1:广度优先搜索

我们以每个长度为4的字符串作为点,每个字符串与其经过一次操作后变换成的字符串所代表的点连边,边权为1,用此方法构造隐式图,最后答案为起点图片说明 到终点 图片说明最短路径
由于图中每条边权都为1,故直接跑广度优先搜索即可求出答案。
代码:

class Solution {
public:
    int solve(string s1, string s2) {
        queue<string> que;
        unordered_map<string,bool> vis;//vis[s]表示字符串s所代表的点是否扩展过
        que.push(s1);
        vis[s1]=true;
        unordered_map<string,int> dis;//dis[s]表示字符串s1所代表的点到字符串s所代表的点的最短路径
        while(!que.empty()){
            string u=que.front();
            que.pop();
            if(u==s2)return dis[u];
            for(int i=0;i<4;i++){//枚举不操作的位置
                string t=u;
                int now=2;
                for(int j=0;j<4;j++){//将剩下3个位置进行变换
                    if(i==j)continue;
                    t[j]=(t[j]-'a'+now)%26+'a';
                    if(now==2)now=3;
                    else now=5;
                }
                if(vis[t])continue;
                que.push(t);
                vis[t]=true;
                dis[t]=dis[u]+1;
            }
        }
        return 0;
    }
};

时间复杂度:图片说明 ,k表示字符集大小,本题为26,显然此隐式图的点数为图片说明 级别的,每个点都只会扩展一次,故时间复杂度为图片说明
空间复杂度:图片说明 ,每个字符串长度为4,可看成一个常数,总共有个点,要存储每个点是否扩展过和每个点的最短路径,故空间复杂度为图片说明

解法2:枚举每个位置的固定次数

题目意思是每次操作都固定1个位置不动,其余3个位置依次变化2、3、5,那么我们可以考虑写四重循环枚举每个位置的不动的次数,然后每种情况都分别计算出每个位置 "" 的值,然后再比较按照此方法是否可以让图片说明 变成图片说明 。最后取出答案的最小值即可。
具体的:
我们分别设图片说明 不动的次数为图片说明
我们再分别设图片说明 ""的值为图片说明

  1. 考虑固定位置0的贡献:
    图片说明
  2. 考虑固定位置1的贡献:
    图片说明
  3. 考虑固定位置2的贡献:
    图片说明
  4. 考虑固定位置3的贡献:
    图片说明
    结合上述,可得:
    图片说明
    考虑枚举每种情况,操作的总次数就是不动的总次数,即图片说明 ,最后答案取每次操作总次数的最小值即可。
    代码:
    class Solution {
    public:
     int solve(string s1, string s2) {
         int cnt[4]={0};
         for(int i=0;i<4;i++){
             cnt[i]=(s2[i]-s1[i]+26)%26;//s1到s2每个位置的差值
         }
         int ans=26*26*26*26;
         for(int a=0;a<=26;a++){//第0个位置固定的次数
             for(int b=0;b<=26;b++){//第1个位置固定的次数
                 for(int c=0;c<=26;c++){//第2个位置固定的次数
                     for(int d=0;d<=26;d++){//第3个位置固定的次数
                         int c0=(b+c+d)*2;//只要第0个位置没有固定,加的值肯定是2
                         //第1个位置只能是加2或者3
                         //加2:第0个位置固定了多少次就加多少次2
                         //加3:第0个和第1个都没有固定,剩下第2个和第3个固定的次数和就是加3的次数
                         int c1=2*a+3*(c+d);
                         //第2个位置只能是加3或者加5
                         int c2=3*(a+b)+5*d;
                         //第3个位置只能加5
                         int c3=(a+b+c)*5;
                         c0%=26;
                         c1%=26;
                         c2%=26;
                         c3%=26;
                         if(c0==cnt[0]&&c1==cnt[1]&&c2==cnt[2]&&c3==cnt[3]){
                             ans=min(ans,a+b+c+d);
                         }
                     }
                 }
             }
         }
         return ans;
     }
    };
    时间复杂度:图片说明为字符集大小,本题为26,由于我们枚举每个位置不动的次数为次,总共有4个位置,故时间复杂度为图片说明
    空间复杂度:图片说明 ,由于字符串长度仅为4,故我们只需要图片说明 级别的数组记录每个位置""的相关信息,故空间复杂度为图片说明