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