这道题采用动态规划毫无疑问,如果直接DP的话时间复杂度为O(n^3),会报TLE错误。需要把时间复杂度降到O(n^2).
下面的代码列出了这两种复杂度的算法。
之所以时间复杂度下降,是因为我不再单独的判断string的某一个substring是否是回文,而是先用一个数组boolean P[][],来保存所有的字串是否是回文。这个判断过程也是采用动态规划过程,其时间复杂度为O(n^2)。
下面是AC代码:
/** * O(n^2) Accepted * Given a string s, partition s such that every substring of the partition is a palindrome. * Return the minimum cuts needed for a palindrome partitioning of s. * @param s * @return */ public int minCut2(String s){ int N = s.length(); boolean[][] P = new boolean[N][N];//whether s[i...j] is palindrome //单个的都是true; for(int i=0;i<N;i++) P[i][i] = true; //bottom up DP process for(int len =2;len<=N;len++) { for(int j =0; j<=N-len;j++){ if(s.charAt(j) == s.charAt(j+len-1)){ P[j][j+len-1] = len==2? true: P[j+1][j+len-2]; } } } // mc is the array to keep the minCut of the sub-problem int[] mc = new int[N]; mc[0] = 0; if (P[0][N-1]) return 0; for (int i = 1; i < N; i++) { mc[i] = mc[i - 1] + 1; int j = i - 1; while (j >= 0) { if (P[j][i]) { if (j == 0) mc[i] = 0; else mc[i] = mc[i] < mc[j - 1] + 1 ? mc[i] : mc[j - 1] + 1; } j--; } } return mc[N - 1]; } /** * O(n^3)复杂度 出现TLE * @param s * @return */ public int minCut(String s){ int N = s.length(); //mc is the array to keep the minCut of the sub-problem int[] mc = new int[N]; mc[0] = 0; if(isPalindrome(s)) return 0 ; for(int i= 1;i<N;i++){ mc[i] = mc[i-1]+1; int j= i-1; while(j>=0){ if(isPalindrome(s.substring(j,i+1))) { if(j==0) mc[i] = 0; else mc[i] = mc[i]< mc[j-1]+1? mc[i]:mc[j-1]+1; } j--; } } return mc[N-1]; } /** * 判断字符串是否是回文 * @param s * @return */ private boolean isPalindrome(String s){ int i=0; int j=s.length()-1; while(i<=j){ if(s.charAt(i++)!=s.charAt(j--)) return false; } return true; }