最长公共子串 发表于 2018-05-25 | 分类于 面试 给定两个字符串str1和str2,返回两个字符串的最长公共子串 解法一:动态规划 12345678910111213141516171819202122232425262728293031323334353637383940414243444546public int[][] getdp(char[] str1, char[] str2){ int[][] dp = nex int[str1.length][str2.length]; for (int i =0; i < str1.length; i++){ if (str1[i] == str2[0]){ dp[i][0] = 1; } } for (int j =0; j < str2.length; j++){ if (str1[0] == str2[j]){ dp[0][j] = 1; } } for (int i = 1; i < str1.length; i++){ for (int j = 1; j < str2.length; j++){ if(str1[i] == str2[j]){ dp[i][j] = dp[i-1][j-1] +1; } } } return dp;}public String lcst1(String str1, String str2){ if (str1 == null || str2 == null || str1 == "" || str2 == ""){ return ""; } char[] chs1 = str1.toCharArray(); char[] chs2 = str2.tocharArray(); int[][] dp = getdp(chs1, chs2); int end = 0; int max = 0; for (int i = 0; i< chs1.length; i++){ for (int j =0; j < chs2.length; j++){ if (dp[i][j] > max){ end = i; max = dp[i][j]; } } } return str1.substring(end-max+1, end+1); } 解法二:从斜线最左上的位置想右下依次计算每个位置的值 123456789101112131415161718192021222324252627282930313233343536373839404142public String lcat2(String str1, String str2){ if (str1 == null || str2 == null || str1 == "" || str2 == ""){ return ""; } char[] chs1 = str1.toCharArray(); char[] chs2 = str2.toCharArray(); int row = 0; int col = chs2.length -1; int max = 0; int end = 0; while(row < chs1.length){ int i = row; int j = col; int len = 0; while (i < chs1.length && j < chs2.length){ if (chs1[i] != chs2[j]){ len = 0; }else{ len++; } //记录最大值,以及结束字符的位置 if (len > max) { end = i; max = len; } i++; j++; } if (col > 0){ col--; } else{ row++; } } return str1.substring(end -max +1,end +1);}