leetcode488

1.转成int处理结果超出int最大值了

class Solution {
public:
    int ret=-1;
    int findMinStep(string board, string hand) {
        int bnum=9;//补一位9
        int hnum[6]={0};
        //RYBGW
        //46125
        for(char ch:board){
            bnum=bnum*10+(ch-'B'+7)/5;
        }
        for(char ch:hand){
            hnum[(ch-'B'+7)/5-1]++;
            hnum[2]++;//记录总数
        }
        backtrack(bnum,0,hnum);
        return ret;
    }
    void backtrack(int bnum,int cnt,int hnum[6]){
        //cout<<"bnum:"<<bnum<<"--"<<"cnt:"<<cnt<<endl;
        if(ret!=-1&&cnt>ret){
            //cout<<"1"<<endl;
            return;
        }
        if(bnum==9){
            if(ret==-1){
                //cout<<"2"<<endl;
                ret=cnt;
            }else{
                //cout<<"3"<<endl;
                ret=ret<cnt?ret:cnt;
            }
        }else{
            if(hnum[2]==0){
                //cout<<"4"<<endl;
                return;
            }
            //是否能消除
            int temp=bnum,num1=0,idx=1,num2=-1;
            while(temp){
                //能用一个消除
                if(temp%10==num1&&hnum[num1-1]>0){
                    hnum[num1-1]--;
                    hnum[2]--;
                    //消除操作
                    //bnum=(bnum/(idx*10))*(idx/10)+bnum%(idx/10);
                    backtrack(removeboard(bnum,idx,idx/10),cnt+1,hnum);
                    hnum[2]++;
                    hnum[num1-1]++;
                //能用两个消除
                }else if(temp%10!=num1&&num1>0&&hnum[num1-1]>1&&(num2!=num1)){
                    hnum[num1-1]-=2;
                    hnum[2]-=2;
                    backtrack(removeboard(bnum,idx/10,idx/10),cnt+2,hnum);
                    hnum[2]+=2;
                    hnum[num1-1]+=2;
                }
                //单独个位数处理
                //if(temp<10&&temp!=num1&&hnum[temp-1]>1){
                //    hnum[temp-1]-=2;
                //    backtrack(0,cnt+2,hnum);
                //    hnum[temp-1]+=2;
                //}
                
                num2=num1!=0?num1:0;
                num1=temp%10;
                temp/=10;
                idx*=10;
            }    
        }
    }
    int removeboard(int bnum,int idx1,int idx2){
        idx1*=10;
        //cout<<"bnum1:"<<bnum<<" bnum2:"<<(bnum/idx1)*idx2+bnum%idx2<<endl;
        bnum=(bnum/idx1)*idx2+bnum%idx2;
        if(idx2==1){
            return bnum;
        }else{
            int temp=idx2==10?bnum%1000:(bnum%(idx2*100))/(idx2/100);
            //cout<<"bnum2:"<<bnum<<" temp:"<<temp<<" idx2:"<<idx2<<endl;
            //46125
            if(temp==4444||temp==6666||temp==1111||temp==2222||temp==5555){
                return removeboard(bnum,idx2*10,idx2/100);
            }
            if(temp/10==444||temp/10==666||temp/10==111||temp/10==222||temp/10==555){
                return removeboard(bnum,idx2*10,idx2/10);
            }
            if(temp%1000==444||temp%1000==666||temp%1000==111||temp%1000==222||temp%1000==555){
                return removeboard(bnum,idx2==10?100:idx2,idx2==10?1:idx2/100);
            }
            return bnum;
        }
    }
};

 2.通过版,数值最后还是放弃了,超出int范围不可测

class Solution {
public:
    int ret=-1;
    int findMinStep(string board, string hand) {
        
        int hnum[6]={0};
        for(char ch:hand){
            hnum[(ch-'B'+7)/5-1]++;
            hnum[2]++;//记录总数
        }
        //if(board.length()<9){
        //    //RYBGW
        //    //46125
        //    int bnum=9;//补一位9
        //    for(char ch:board){
        //        bnum=bnum*10+(ch-'B'+7)/5;
        //    }
        //    
        //    backtrack(bnum,0,hnum);
        //}else{
        //    backtrack_(board+"Z",0,hnum);
        //}
        backtrack_(board+"Z",0,hnum);
        return ret;
    }
    void backtrack_(string board,int cnt,int hnum[6]){
        //cout<<"board:"<<board<<endl;
        if(ret!=-1&&cnt>ret){
            //cout<<"1"<<endl;
            return;
        }
        if(board=="Z"){
            if(ret==-1){
                //cout<<"2"<<endl;
                ret=cnt;
            }else{
                //cout<<"3"<<endl;
                ret=ret<cnt?ret:cnt;
            }
        }else{
            if(hnum[2]==0){
                //cout<<"4"<<endl;
                return;
            }
            //是否能消除
            int num1;
            char ch1='a',ch2='b';
            //RYBGW
            //46125
            string dict="BG RWY";
            for(int i=0;i<board.length();++i){
                num1=(ch1-'B'+7)/5;
                if(board[i]==ch1&&hnum[num1-1]>0){
                    hnum[num1-1]--;
                    hnum[2]--;
                    //消除操作后进入下一步
                    backtrack_(removeboard_(board,i-1,2),cnt+1,hnum);
                    hnum[2]++;
                    hnum[num1-1]++;
                //能用两个消除
                }else if(board[i]!=ch1&&ch1!='a'&&hnum[num1-1]>1&&(ch2!=ch1)){
                    hnum[num1-1]-=2;
                    hnum[2]-=2;
                    backtrack_(removeboard_(board,i-1,1),cnt+2,hnum);
                    hnum[2]+=2;
                    hnum[num1-1]+=2;
                }
                //不消除插入
                for(int j=0;j<6;++j){
                    if(j!=2&&hnum[j]>0&&((board[i]==ch1&&(num1-1)!=j))){
                        hnum[j]--;
                        string board_=board;
                        string temp=board.insert(i,1,dict[j]);
                        board=board_;
                        backtrack_(temp,cnt+1,hnum);
                        hnum[j]++;
                    }
                }
                ch2=ch1!='a'?ch1:ch2;
                ch1=board[i];
            }
        }
    }
    string removeboard_(string board,int idx,int len){
        string board_=board;
        string str=board.replace(idx,len,"");
        board=board_;
        //cout<<"board1:"<<board_<<" idx:"<<idx<<" len:"<<len<<" str:"<<str<<endl;
        if(idx==0){
            return str;
        }else{
            string temp=str.substr(idx-2==-1?0:idx-2,idx-2==-1?1:2)+str.substr(idx,2);
            int idx1=idx-2==-1?0:idx-2,len1=1;
            for(int i=1;i<temp.length();++i){
                if(temp[i]==temp[i-1]){
                    len1++;
                }else if(i<3){
                    idx1++;
                    len1=1;
                }
            }
            //cout<<"str:"<<str<<" idx1:"<<idx1<<" len1:"<<len1<<" temp:"<<temp<<endl;
            if(len1>2){
                return removeboard_(str,idx1,len1);
            }
            return str;
        }
    }
    void backtrack(int bnum,int cnt,int hnum[6]){
        //cout<<"bnum:"<<bnum<<"--"<<"cnt:"<<cnt<<endl;
        if(ret!=-1&&cnt>ret){
            //cout<<"1"<<endl;
            return;
        }
        if(bnum==9){
            if(ret==-1){
                //cout<<"2"<<endl;
                ret=cnt;
            }else{
                //cout<<"3"<<endl;
                ret=ret<cnt?ret:cnt;
            }
        }else{
            if(hnum[2]==0){
                //cout<<"4"<<endl;
                return;
            }
            //是否能消除
            int temp=bnum,num1=0,idx=1,num2=-1;
            while(temp){
                //能用一个消除
                if(temp%10==num1&&hnum[num1-1]>0){
                    hnum[num1-1]--;
                    hnum[2]--;
                    //消除操作
                    //bnum=(bnum/(idx*10))*(idx/10)+bnum%(idx/10);
                    backtrack(removeboard(bnum,idx,idx/10),cnt+1,hnum);
                    hnum[2]++;
                    hnum[num1-1]++;
                //能用两个消除
                }else if(temp%10!=num1&&num1>0&&hnum[num1-1]>1&&(num2!=num1)){
                    hnum[num1-1]-=2;
                    hnum[2]-=2;
                    backtrack(removeboard(bnum,idx/10,idx/10),cnt+2,hnum);
                    hnum[2]+=2;
                    hnum[num1-1]+=2;
                }
                //不消除插入
                for(int j=0;j<6;++j){
                    if(j!=2&&hnum[j]>0&&((temp%10==num1&&(num1-1)!=j)||temp%10!=num1)){
                        hnum[j]--;
                        backtrack((bnum/idx)*(idx*10)+(j+1)*idx+bnum%idx,cnt+1,hnum);
                        hnum[j]++;
                    }
                }
                num2=num1!=0?num1:0;
                num1=temp%10;
                temp/=10;
                idx*=10;
            }    
        }
    }
    int removeboard(int bnum,int idx1,int idx2){
        idx1*=10;
        //cout<<"bnum1:"<<bnum<<" bnum2:"<<(bnum/idx1)*idx2+bnum%idx2<<endl;
        bnum=(bnum/idx1)*idx2+bnum%idx2;
        if(idx2==1){
            return bnum;
        }else{
            int temp=idx2==10?bnum%1000:(bnum%(idx2*100))/(idx2/100);
            //cout<<"bnum2:"<<bnum<<" temp:"<<temp<<" idx2:"<<idx2<<endl;
            //46125
            if(temp==4444||temp==6666||temp==1111||temp==2222||temp==5555){
                return removeboard(bnum,idx2*10,idx2/100);
            }
            if(temp/10==444||temp/10==666||temp/10==111||temp/10==222||temp/10==555){
                return removeboard(bnum,idx2*10,idx2/10);
            }
            if(temp%1000==444||temp%1000==666||temp%1000==111||temp%1000==222||temp%1000==555){
                return removeboard(bnum,idx2==10?100:idx2,idx2==10?1:idx2/100);
            }
            return bnum;
        }
    }
};

 3.加了hashset减枝,减少了计算次数,但总体时间没变多少

class Solution {
public:
    int ret=-1;
    string dict="BG RWY";
    unordered_set<string> uset;
    int cnt1=0;
    int findMinStep(string board, string hand) {
        int hnum[6]={0};
        for(char ch:hand){
            hnum[(ch-'B'+7)/5-1]++;
            hnum[2]++;//记录总数
        }
        //if(board.length()<9){
        //    //RYBGW
        //    //46125
        //    int bnum=9;//补一位9
        //    for(char ch:board){
        //        bnum=bnum*10+(ch-'B'+7)/5;
        //    }
        //    
        //    backtrack(bnum,0,hnum);
        //}else{
        //    backtrack_(board+"Z",0,hnum);
        //}
        backtrack_(board+"Z",0,hnum);
        //cout<<cnt1<<endl;
        return ret;
    }
    void backtrack_(string board,int cnt,int hnum[6]){
        if(uset.count(board)>0&&(cnt>ret)){
            cnt1++;
            return;
        }else{
            uset.emplace(board);
        }
        
        //cout<<"board:"<<board<<endl;
        if(ret!=-1&&cnt>ret){
            //cout<<"1"<<endl;
            return;
        }
        if(board=="Z"){
            if(ret==-1){
                //cout<<"2"<<endl;
                ret=cnt;
            }else{
                //cout<<"3"<<endl;
                ret=ret<cnt?ret:cnt;
            }
        }else{
            if(hnum[2]==0){
                //cout<<"4"<<endl;
                return;
            }
            //是否能消除
            int num1;
            char ch1='a',ch2='b';
            //RYBGW
            //46125
            for(int i=0;i<board.length();++i){
                num1=(ch1-'B'+7)/5;
                if(board[i]==ch1&&hnum[num1-1]>0){
                    hnum[num1-1]--;
                    hnum[2]--;
                    //消除操作后进入下一步
                    backtrack_(removeboard_(board,i-1,2),cnt+1,hnum);
                    hnum[2]++;
                    hnum[num1-1]++;
                //能用两个消除
                }else if(board[i]!=ch1&&ch1!='a'&&hnum[num1-1]>1&&(ch2!=ch1)){
                    hnum[num1-1]-=2;
                    hnum[2]-=2;
                    backtrack_(removeboard_(board,i-1,1),cnt+2,hnum);
                    hnum[2]+=2;
                    hnum[num1-1]+=2;
                }
                //不消除插入
                for(int j=0;j<6;++j){
                    if(j!=2&&hnum[j]>0&&((board[i]==ch1&&(num1-1)!=j))){
                        hnum[j]--;
                        string board_=board;
                        string temp=board.insert(i,1,dict[j]);
                        board=board_;
                        backtrack_(temp,cnt+1,hnum);
                        hnum[j]++;
                    }
                }
                ch2=ch1!='a'?ch1:ch2;
                ch1=board[i];
            }
        }
    }
    string removeboard_(string board,int idx,int len){
        string board_=board;
        string str=board.replace(idx,len,"");
        board=board_;
        //cout<<"board1:"<<board_<<" idx:"<<idx<<" len:"<<len<<" str:"<<str<<endl;
        if(idx==0){
            return str;
        }else{
            string temp=str.substr(idx-2==-1?0:idx-2,idx-2==-1?1:2)+str.substr(idx,2);
            int idx1=idx-2==-1?0:idx-2,len1=1;
            for(int i=1;i<temp.length();++i){
                if(temp[i]==temp[i-1]){
                    len1++;
                }else if(i<3){
                    idx1++;
                    len1=1;
                }
            }
            //cout<<"str:"<<str<<" idx1:"<<idx1<<" len1:"<<len1<<" temp:"<<temp<<endl;
            if(len1>2){
                return removeboard_(str,idx1,len1);
            }
            return str;
        }
    }
    void backtrack(int bnum,int cnt,int hnum[6]){
        //cout<<"bnum:"<<bnum<<"--"<<"cnt:"<<cnt<<endl;
        if(ret!=-1&&cnt>ret){
            //cout<<"1"<<endl;
            return;
        }
        if(bnum==9){
            if(ret==-1){
                //cout<<"2"<<endl;
                ret=cnt;
            }else{
                //cout<<"3"<<endl;
                ret=ret<cnt?ret:cnt;
            }
        }else{
            if(hnum[2]==0){
                //cout<<"4"<<endl;
                return;
            }
            //是否能消除
            int temp=bnum,num1=0,idx=1,num2=-1;
            while(temp){
                //能用一个消除
                if(temp%10==num1&&hnum[num1-1]>0){
                    hnum[num1-1]--;
                    hnum[2]--;
                    //消除操作
                    //bnum=(bnum/(idx*10))*(idx/10)+bnum%(idx/10);
                    backtrack(removeboard(bnum,idx,idx/10),cnt+1,hnum);
                    hnum[2]++;
                    hnum[num1-1]++;
                //能用两个消除
                }else if(temp%10!=num1&&num1>0&&hnum[num1-1]>1&&(num2!=num1)){
                    hnum[num1-1]-=2;
                    hnum[2]-=2;
                    backtrack(removeboard(bnum,idx/10,idx/10),cnt+2,hnum);
                    hnum[2]+=2;
                    hnum[num1-1]+=2;
                }
                //不消除插入
                for(int j=0;j<6;++j){
                    if(j!=2&&hnum[j]>0&&((temp%10==num1&&(num1-1)!=j)||temp%10!=num1)){
                        hnum[j]--;
                        backtrack((bnum/idx)*(idx*10)+(j+1)*idx+bnum%idx,cnt+1,hnum);
                        hnum[j]++;
                    }
                }
                num2=num1!=0?num1:0;
                num1=temp%10;
                temp/=10;
                idx*=10;
            }    
        }
    }
    int removeboard(int bnum,int idx1,int idx2){
        idx1*=10;
        //cout<<"bnum1:"<<bnum<<" bnum2:"<<(bnum/idx1)*idx2+bnum%idx2<<endl;
        bnum=(bnum/idx1)*idx2+bnum%idx2;
        if(idx2==1){
            return bnum;
        }else{
            int temp=idx2==10?bnum%1000:(bnum%(idx2*100))/(idx2/100);
            //cout<<"bnum2:"<<bnum<<" temp:"<<temp<<" idx2:"<<idx2<<endl;
            //46125
            if(temp==4444||temp==6666||temp==1111||temp==2222||temp==5555){
                return removeboard(bnum,idx2*10,idx2/100);
            }
            if(temp/10==444||temp/10==666||temp/10==111||temp/10==222||temp/10==555){
                return removeboard(bnum,idx2*10,idx2/10);
            }
            if(temp%1000==444||temp%1000==666||temp%1000==111||temp%1000==222||temp%1000==555){
                return removeboard(bnum,idx2==10?100:idx2,idx2==10?1:idx2/100);
            }
            return bnum;
        }
    }
};

 4.优化版,有待优化hashset没起到作用

 

class Solution {
public:
    int ret=-1;
    string dict="BG RWY",board_="",temp="",str="";
    //unordered_set<string> uset;
    int hnum[6]={0};
    //int cnt1=0,cnt2=0;
    int findMinStep(string board, string hand) {
        for(char ch:hand){
            hnum[(ch-'B'+7)/5-1]++;
            hnum[2]++;//记录总数
        }
        backtrack_(board+"Z",0);
        //cout<<cnt1<<endl;
        //cout<<cnt2<<endl;
        return ret;
    }
    void backtrack_(string board,int cnt){
        //cnt2++;
        //cout<<"board:"<<board<<endl;
        if(ret!=-1&&cnt>ret){
            //cout<<"1"<<endl;
            return;
        }
        
        if(board=="Z"){
            if(ret==-1){
                //cout<<"2"<<endl;
                ret=cnt;
            }else{
                //cout<<"3"<<endl;
                ret=ret<cnt?ret:cnt;
            }
        }else{
            //if(uset.count(board)>0&&(cnt>ret)){
            //    cnt1++;
            //    return;
            //}else{
            //    uset.emplace(board);
            //}
            if(hnum[2]==0){
                //cout<<"4"<<endl;
                return;
            }
            //是否能消除
            int num1;
            char ch1='a',ch2='b';
            //RYBGW
            //46125
            for(int i=0;i<board.length();++i){
                num1=(ch1-'B'+7)/5;
                if(board[i]==ch1&&hnum[num1-1]>0){
                    hnum[num1-1]--;
                    hnum[2]--;
                    //消除操作后进入下一步
                    backtrack_(removeboard_(board,i-1,2),cnt+1);
                    hnum[2]++;
                    hnum[num1-1]++;
                //能用两个消除
                }else if(board[i]!=ch1&&ch1!='a'&&hnum[num1-1]>1&&(ch2!=ch1)){
                    hnum[num1-1]-=2;
                    hnum[2]-=2;
                    backtrack_(removeboard_(board,i-1,1),cnt+2);
                    hnum[2]+=2;
                    hnum[num1-1]+=2;
                }
                //不消除插入
                for(int j=0;j<6;++j){
                    if(j!=2&&hnum[j]>0&&((board[i]==ch1&&(num1-1)!=j))){
                        hnum[j]--;
                        hnum[2]--;
                        board_=board;
                        temp=board.insert(i,1,dict[j]);
                        board=board_;
                        backtrack_(temp,cnt+1);
                        hnum[2]++;
                        hnum[j]++;
                    }
                }
                ch2=ch1!='a'?ch1:ch2;
                ch1=board[i];
            }
        }
    }
    string removeboard_(string board,int idx,int len){
        board_=board;
        str=board.replace(idx,len,"");
        board=board_;
        //cout<<"board1:"<<board_<<" idx:"<<idx<<" len:"<<len<<" str:"<<str<<endl;
        if(idx==0){
            return str;
        }else{
            temp=str.substr(idx-2==-1?0:idx-2,idx-2==-1?1:2)+str.substr(idx,2);
            int idx1=idx-2==-1?0:idx-2,len1=1;
            for(int i=1;i<temp.length();++i){
                if(temp[i]==temp[i-1]){
                    len1++;
                }else if(i<3){
                    idx1++;
                    len1=1;
                }
            }
            //cout<<"str:"<<str<<" idx1:"<<idx1<<" len1:"<<len1<<" temp:"<<temp<<endl;
            if(len1>2){
                return removeboard_(str,idx1,len1);
            }
            return str;
        }
    }
};

 5.hashset优化

 

class Solution {
public:
    int ret=-1;
    string dict="BG RWY",board_="",temp="";
    //unordered_set<string> uset;
    unordered_map <string, int> umap; 
    int hnum[6]={0};
    //int cnt1=0,cnt2=0;
    int findMinStep(string board, string hand) {
        for(char ch:hand){
            hnum[(ch-'B'+7)/5-1]++;
            hnum[2]++;//记录总数
        }
        backtrack_(board+"Z",0);
        //cout<<cnt1<<endl;
        //cout<<cnt2<<endl;
        return ret;
    }
    void backtrack_(string board,int cnt){
        //cnt2++;
        if(ret!=-1&&cnt>=ret){
            return;
        }
        
        if(board=="Z"){
            if(ret==-1){
                //cout<<"2"<<endl;
                ret=cnt;
            }else{
                //cout<<"3"<<endl;
                ret=ret<cnt?ret:cnt;
            }
        }else{
            //if(uset.count(board)>0&&(cnt>ret)){
            //    cnt1++;
            //    return;
            //}else{
            //    uset.emplace(board);
            //}
            if(umap.count(board)>0){
                //cnt1++;
                if(cnt>=umap[board]){
                    //cnt1++;
                    return;
                }else{
                    umap[board]=cnt;
                }
                //return;
            }else{
                umap.emplace(make_pair(board, cnt));
            }
            if(hnum[2]==0){
                //cout<<"4"<<endl;
                return;
            }
            //是否能消除
            int num1;
            char ch1='a',ch2='b';
            //RYBGW
            //46125
            for(int i=0;i<board.length();++i){
                num1=(ch1-'B'+7)/5;
                if(board[i]==ch1&&hnum[num1-1]>0){
                    hnum[num1-1]--;
                    hnum[2]--;
                    //消除操作后进入下一步
                    backtrack_(removeboard_(board,i-1,2),cnt+1);
                    hnum[2]++;
                    hnum[num1-1]++;
                //能用两个消除
                }else if(board[i]!=ch1&&ch1!='a'&&hnum[num1-1]>1&&(ch2!=ch1)){
                    hnum[num1-1]-=2;
                    hnum[2]-=2;
                    backtrack_(removeboard_(board,i-1,1),cnt+2);
                    hnum[2]+=2;
                    hnum[num1-1]+=2;
                }
                //不消除插入
                for(int j=0;j<6;++j){
                    if(j!=2&&hnum[j]>0&&((board[i]==ch1&&(num1-1)!=j))){
                        board_=board;
                        temp=board.insert(i,1,dict[j]);
                        board=board_;
                        //if(uset.count(temp)>0){
                        //    //cnt1++;
                        //    continue;
                        //}else{
                        //    uset.emplace(temp);
                        //}
                        hnum[j]--;
                        hnum[2]--;
                        backtrack_(temp,cnt+1);
                        hnum[2]++;
                        hnum[j]++;
                    }
                }
                ch2=ch1!='a'?ch1:ch2;
                ch1=board[i];
            }
        }
    }
    string removeboard_(string board,int idx,int len){
        //board_=board;
        board.replace(idx,len,"");
        if(idx==0){
            return board;
        }else{
            temp=board.substr(idx-2==-1?0:idx-2,idx-2==-1?1:2)+board.substr(idx,2);
            int idx1=idx-2==-1?0:idx-2,len1=1;
            for(int i=1;i<temp.length();++i){
                if(temp[i]==temp[i-1]){
                    len1++;
                }else if(i<3){
                    idx1++;
                    len1=1;
                }
            }
            //cout<<"str:"<<str<<" idx1:"<<idx1<<" len1:"<<len1<<" temp:"<<temp<<endl;
            if(len1>2){
                return removeboard_(board,idx1,len1);
            }
            return board;
        }
    }
};

 

 

posted @ 2021-11-10 11:50  巴啦啦大魔王  阅读(70)  评论(0编辑  收藏  举报