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

     

  • 相关阅读:
    linux基础知识-12
    linux基础知识-11
    linux基础知识-10
    安装与迁移Solo博客系统
    linux基础知识-9
    linux基础知识-8
    linux基础知识-7
    linux基础知识-6
    linux基础知识-5
    通俗解释下分布式、高并发、多线程
  • 原文地址:https://www.cnblogs.com/Babylon/p/15532826.html
Copyright © 2020-2023  润新知