LeetCode-Restore IP Addresses-恢复IP地址-DP优化
https://oj.leetcode.com/problems/restore-ip-addresses/
跟Word Break II一个尿性的DP题目。如果直接使用vector <string> dp[][]来进行DP会引入很大量的中间结果影响效率。因此可以先用bool dp[][]来计算出那些是合法的。然后DP过程忽略掉很多不合法的结果。
需要注意的是判断s[k,j)是否为合法IP分段也需要在第二次DP中进行。同时需要注意分配d[5][]而不是dp[4][],否则会运行错误。
const int MAX_N=2000; class Solution { public: int n,m; vector<vector<bool>> dp; vector <string> dps[5][MAX_N+1]; int GetInt(string &s){ stringstream ss; ss.str(s); int res; ss>>res; return res; } vector<string> restoreIpAddresses(string s) { n=s.length(); dp.resize(5,vector<bool>(n+1,false)); dp[0][0]=true; for (int i=1;i<=4;i++){ for (int j=1;j<=n;j++){ dp[i][j]=false; for (int k=j-3;k<j;k++){ if (k<0){continue;} string curs=s.substr(k,j-k); if (curs.length()>1){ if (curs[0]=='0'){continue;} } int cur=GetInt(curs); if (cur>255){continue;} dp[i][j] =dp[i][j] || dp[i-1][k]; } } } dps[0][0].push_back(""); for (int i=1;i<=4;i++){ for (int j=1;j<=n;j++){ if (!dp[i][j]){continue;} vector<string> &dst=dps[i][j]; for (int k=j-3;k<j;k++){ if (k<0){continue;} if (!dp[i-1][k]){continue;} string curs=s.substr(k,j-k); if (curs.length()>1){ if (curs[0]=='0'){continue;} } int cur=GetInt(curs); if (cur>255){continue;} vector<string> &pres=dps[i-1][k]; for (int ii=0;ii<pres.size();ii++){ string temp=pres[ii]; if (pres[ii].length()>0){ temp+="."; } temp+=curs; dst.push_back(temp); } } } } return dps[4][n]; } };