From fdab79726dc50af1d5a0f30869ec53dec83c00ae Mon Sep 17 00:00:00 2001 From: algorithmzuo Date: Fri, 24 Dec 2021 23:26:10 +0800 Subject: [PATCH] modify code --- .../Code04_LongestCommonSubsequence.java | 49 +++++++------------ 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/src/class19/Code04_LongestCommonSubsequence.java b/src/class19/Code04_LongestCommonSubsequence.java index 7146e1e..5e49551 100644 --- a/src/class19/Code04_LongestCommonSubsequence.java +++ b/src/class19/Code04_LongestCommonSubsequence.java @@ -15,36 +15,25 @@ public class Code04_LongestCommonSubsequence { } // str1[0...i]和str2[0...j],这个范围上最长公共子序列长度是多少? - // 可能性分类: - // a) 最长公共子序列,既不以str1[i]字符结尾、也不以str2[j]字符结尾 - // 比如: str1[0..5] = "1a234b", str2[0..7] = "cd12e34f" - // 其中最长公共子序列为"1234" - // 可以看到,这个最长公共子序列根本和str1[i]字符、str2[j]字符没有任何关系 - // a)的可能性下,最长公共子序列总长度 = - // str1[0...i-1]与str2[0...j-1]的最长公共子序列长度(后续递归) - // ====================================================== - // b) 最长公共子序列,以str1[i]字符结尾、不以str2[j]字符结尾 - // 比如: str1[0..5] = "1a23b4", str2[0..7] = "cd12e34f" - // 其中最长公共子序列为"1234" - // 可以看到,这个最长公共子序列以str1[i]字符结尾,但是不以str2[j]字符结尾 - // b)的可能性下,最长公共子序列总长度 = - // str1[0...i]与str2[0...j-1]的最长公共子序列长度(后续递归) - // ====================================================== - // c) 最长公共子序列,不以str1[i]字符结尾、以str2[j]字符结尾 - // 比如: str1[0..5] = "1a234b", str2[0..7] = "cd12e3f4" - // 其中最长公共子序列为"1234" - // 可以看到,这个最长公共子序列不以str1[i]字符结尾,以str2[j]字符结尾 - // c)的可能性下,最长公共子序列总长度 = - // str1[0...i-1]与str2[0...j]的最长公共子序列长度(后续递归) - // ====================================================== - // d) 最长公共子序列,同时以str1[i]字符和str2[j]字符结尾 - // 比如: str1[0..5] = "1a23b4", str2[0..7] = "cd12ef34" - // 其中最长公共子序列为"1234" - // 可以看到这个公共子序列的结尾是'4',同时以str1[5]字符和str2[7]字符结尾 - // 同时可以看到,可能性d)存在的条件,一定是在str1[i] == str2[j]的情况下,才成立的 - // d)的可能性下,最长公共子序列总长度 = - // str1[0...i-1]与str2[0...j-1]的最长公共子序列长度(后续递归) + 1(共同的结尾) - // ====================================================== + // 可能性分类: + // a) 最长公共子序列,一定不以str1[i]字符结尾、也一定不以str2[j]字符结尾 + // b) 最长公共子序列,可能以str1[i]字符结尾、但是一定不以str2[j]字符结尾 + // c) 最长公共子序列,一定不以str1[i]字符结尾、但是可能以str2[j]字符结尾 + // d) 最长公共子序列,必须以str1[i]字符结尾、也必须以str2[j]字符结尾 + // 注意:a)、b)、c)、d)并不是完全互斥的,他们可能会有重叠的情况 + // 但是可以肯定,答案不会超过这四种可能性的范围 + // 那么我们分别来看一下,这几种可能性怎么调用后续的递归。 + // a) 最长公共子序列,一定不以str1[i]字符结尾、也一定不以str2[j]字符结尾 + // 如果是这种情况,那么有没有str1[i]和str2[j]就根本不重要了,因为这两个字符一定没用啊 + // 所以砍掉这两个字符,最长公共子序列 = str1[0...i-1]与str2[0...j-1]的最长公共子序列长度(后续递归) + // b) 最长公共子序列,可能以str1[i]字符结尾、但是一定不以str2[j]字符结尾 + // 如果是这种情况,那么我们可以确定str2[j]一定没有用,要砍掉;但是str1[i]可能有用,所以要保留 + // 所以,最长公共子序列 = str1[0...i]与str2[0...j-1]的最长公共子序列长度(后续递归) + // c) 最长公共子序列,一定不以str1[i]字符结尾、但是可能以str2[j]字符结尾 + // 跟上面分析过程类似,最长公共子序列 = str1[0...i-1]与str2[0...j]的最长公共子序列长度(后续递归) + // d) 最长公共子序列,必须以str1[i]字符结尾、也必须以str2[j]字符结尾 + // 同时可以看到,可能性d)存在的条件,一定是在str1[i] == str2[j]的情况下,才成立的 + // 所以,最长公共子序列总长度 = str1[0...i-1]与str2[0...j-1]的最长公共子序列长度(后续递归) + 1(共同的结尾) // 综上,四种情况已经穷尽了所有可能性。四种情况中取最大即可 // 其中b)、c)一定参与最大值的比较, // 当str1[i] == str2[j]时,a)一定比d)小,所以d)参与