剑指offer48 最长不含重复字符的子字符串
看到最长,先想DP。
暴力解法找到所有子字符串O(n^2)再O(n)判断是否重复,O(n^3)。从n中选一个开头,再从n中选一个结束,再去掉一般不是字符串的(开头大于结束)。
牛客网上又没有。这个值得写一下:
public class niuke48 { public String longestSubStringWithoutRepeat(String s) { if(s==null||s.length()<1) return ""; int[] dp = new int[s.length()]; int[] pos = new int[26]; for(int i=0;i<pos.length;i++) pos[i]=-1; dp[0]=1;pos[s.charAt(0)-'a']=0; int max = dp[0];int maxIndex=0; //dp[i] 表示以charAt(i)结尾的子字符串最长无重复长度 for(int i=1;i<s.length();i++) { char c = s.charAt(i); if(pos[c-'a']==-1) dp[i]=dp[i-1]+1; else { if(i-pos[c-'a']<=dp[i-1]) dp[i]=i-pos[c-'a']; else dp[i]=dp[i-1]+1; } if(dp[i]>max) {max=dp[i];maxIndex=i;} } return s.substring(maxIndex-max, maxIndex+1); } }
用pos记录字符上次出现的位置的思路挺好的。
class Solution(object): def getSubstring(self, astr): if astr is None or len(astr)<0: return "" dp = [0 for i in range(len(astr))] pos = [-1 for i in range(26)] dp[0] = 1 pos[ord(astr[0])-ord('a')] = 0 for i in range(1,len(astr)): asc2 = ord(astr[i])-ord('a') if pos[asc2]==-1: pos[asc2] = i dp[i] = dp[i-1]+1 elif pos[asc2]<i-dp[i-1]: pos[asc2] = i dp[i] = dp[i - 1] + 1 else: dp[i] = i-pos[asc2] pos[asc2] = i return max(dp) if __name__=='__main__': sol = Solution() print sol.getSubstring("arabcacfr")

浙公网安备 33010602011771号