akka stream第三課-模組化
阿新 • • 發佈:2020-09-17
LeetCode 5 最長迴文子串
問題描述:
給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為 1000。
動態規劃
執行用時:209 ms, 在所有 Java 提交中擊敗了12.42%的使用者
記憶體消耗:50.1 MB, 在所有 Java 提交中擊敗了5.01%的使用者
class Solution{ //動態規劃 //dp[i][j]表示str[i, j]範圍內最長迴文子串長度, j>=i //dp[i][j]與dp[i+1][j]、dp[i][j-1]、dp[i+1][j-1]有關 //1. 若str[i]==str[j] and dp[i+1][j-1]==j-(i+1) // dp[i][j] = dp[i+1][j-1]+2 //2. 其它情況 // dp[i][j] = max{dp[i+1][j], dp[i][j-1], dp[i+1][j-1]} //初始: dp[i][i] = 1 public String longestPalindrome(String s) { if(s==null || s.length()<=1) { return s; } int[][] dp = new int[s.length()][s.length()]; //狀態初始化 for(int i=0; i<s.length(); i++) { dp[i][i] = 1; } //狀態遞推O(N2) int left = 0, right = 0; //遍歷方式存在問題(保證後有效性) for(int j=0; j<s.length(); j++) { for(int i=0; i<=j; i++) { if(i==j) { continue; } //考慮奇對稱、偶對稱兩種情況下的初始情況(兩個值、三個值) if(s.charAt(i)==s.charAt(j) && (i+1==j || dp[i+1][j-1]==(j-i-1))) { dp[i][j] = j+1-i; } else { dp[i][j] = Math.max( i+1==j? 0: dp[i+1][j-1], Math.max(dp[i+1][j], dp[i][j-1]) ); } //記錄字串起始座標 if(right+1-left < dp[i][j] && dp[i][j]==j+1-i) { left = i; right = j; } } } return s.substring(left, right+1); } }
暴力優化: 中心擴散
執行用時:58 ms, 在所有 Java 提交中擊敗了59.81%的使用者
記憶體消耗:37.6 MB, 在所有 Java 提交中擊敗了67.40%的使用者
//問題描述:在給定字串中找到最長的迴文“子串”,迴文子串的定義為:字串對稱分佈,即從左到右、從右到左遍歷輸出一致 /**動態規劃: * 狀態轉移:Sub[i,j]表示arr[i]..arr[j]組成的子串 * 若Sub[i,j]是迴文串,則需要滿足:Sub[i+1,j-1]是迴文串,且arr[i] == arr[j] * 遞推:找到一個最小的迴文串,例如"aa"、"aba",由該回文串向外擴充套件 * */ //O(N2/2) class Solution{ public String longestPalindrome(String s) { if(s.length()<=1) return s; if(s.length()==2) return (s.charAt(0)==s.charAt(1))?s:s.charAt(0)+""; int maxLen = 1, minLeft = 0, maxRight = 0; //1、找到一個最小的迴文串(由第二個向倒數第二個尋找) //2、由最小回文串向兩邊擴充套件,找到一個最長的迴文串 //時間複雜度:O(N2) for(int i=1;i<s.length()-1;i++){ //偶數 if(s.charAt(i)==s.charAt(i-1)){ int currLen = searchPalindrome(s, i-1, i); if(maxLen < currLen){ maxLen = currLen; minLeft = i - currLen/2; maxRight = i-1 + currLen/2; } } if(s.charAt(i) == s.charAt(i+1)){ int currLen = searchPalindrome(s, i, i+1); if(maxLen < currLen){ maxLen = currLen; minLeft = i+1 - currLen/2; maxRight = i + currLen/2; } } //奇數 if(s.charAt(i-1)==s.charAt(i+1)){ int currLen = searchPalindrome(s, i-1, i+1); if(maxLen < currLen){ maxLen = currLen; minLeft = i - currLen/2; maxRight = i + currLen/2; } } } System.out.println("maxLen="+maxLen); return s.substring(minLeft, maxRight+1); } public int searchPalindrome(String s, int i, int j){ int maxLen = j-i+1; i--;j++; while(i>=0 && j<s.length()){ if(s.charAt(i) != s.charAt(j)) break; maxLen += 2; i--;j++; } return maxLen; } }