Leetcode-个人题解718

LEETCODE专题


718. Maximum Length of Repeated Subarray

题目要求:
这里写图片描述


算法思路:

   这里,题目要求我们要将A、B中的最长匹配子串的长度找出来。为此,我们思考一个问题:该问题的子问题是什么?
   很明显,该问题的子问题是其前缀问题。
   设想一下,假设s为A中的最长匹配子串,p为B中的最长匹配子串,那么截取掉A中s之后的字符和对应的B中p之后的字符,s与p仍可匹配;而在此基础上截取掉s的最后一个字符和p的最后一个字符,s与p仍可匹配(假设s、p足够长),只不过最大长度减少了1;......

   接下来,按照动态规划问题的思路,我们很自然地会想到下一个问题:如何让其子问题的解能够复用?
   对此,笔者有自己的一番见解(这纯属一家之言,如果读者有更好的见解可以在下方评论提出)。假如说我们单纯地将最大长度作为我们的列表元素,那么后面的复用是非常困难的,因为最长子串有可能并不是以当前下标结尾的。
    比如说输入为
        A:[1, 2, 3, 1, 2, 3, 4]
        B:[1, 2, 3, 4]
    当A为[1, 2, 3, 1], B为[1, 2, 3, 4], 很明显这时候的最大长度是3,最长匹配子串是[1, 2, 3],而这并不以A的结尾为结尾,所以当A的下标再增大时,就会出现子串不连续的情况(跳过了1)。而这显然不是我们想要的答案。
    所以笔者想到的是,列表元素记录结尾于当前字符下标的匹配子串的长度。这样我们就可以通过一个二重循环得到所有的匹配子串的长度。
    最后再用一个变量来存储最大的长度即可。
    仍然用上面的例子来说明下:
        A:[1, 2, 3, 1, 2, 3, 4]
        B:[1, 2, 3, 4]
    当A为[1, 2, 3, 1],B为[1, 2, 3, 4],这时候我们以A为外重循环,B为内重循环的话,可以得到A的末尾1与B的末尾4并不匹配,所以匹配长度为0。
    当A为[1,2,3,1],B为[1]时,匹配长度为1;当A为[1,2,3,1,2],B为[1,2]时,匹配长度为2;当A为[1,2,3,1,2,3],B为[1,2,3]时,匹配长度为3;当A为[1,2,3,1,2,3,4],B为[1,2,3,4]时,匹配长度为4。

下面给出代码:

class Solution {
public:

    /*
     * My solution is to find the length of the
     * matched substring which must be ended in the
     * last char of ArrayA and ArrayB, which means
     * the last char of both array is the same.
     * A DOUBLE LOOP is going to be used to find the
     * longest matched substring.
     * 
     */
    int findLength(vector<int>& A, vector<int>& B) {
        // initial the 2-d array for the last inedx
        // -1 stands for there is no matched char
        int A_index, B_index, A_end, B_end;
        A_index = B_index = 0;
        A_end = A.size();
        B_end = B.size();
        int ** length_of_last_char_A_of_B = new int*[A_end];
        for(A_index = 0; A_index < A_end; A_index++) {
            length_of_last_char_A_of_B[A_index] = new int[B_end];
        }

        // main loop
        int max = 0;
        for (A_index = 0; A_index < A_end; A_index++) {
            for (B_index = 0; B_index < B_end; B_index++) {
                if (B_index == 0) {
                    if (A[A_index] == B[0]) {
                        length_of_last_char_A_of_B[A_index][0] = 1;
                    } else {
                        length_of_last_char_A_of_B[A_index][0] = 0;
                    }
                } else {
                    if (A[A_index] == B[B_index]) {
                        if (A_index != 0) {
                            length_of_last_char_A_of_B[A_index][B_index] = length_of_last_char_A_of_B[A_index - 1][B_index - 1] + 1;
                        } else {
                            length_of_last_char_A_of_B[A_index][B_index] = 1;
                        }
                    } else {
                        // for understanding more easily
                        length_of_last_char_A_of_B[A_index][B_index] = 0;
                    }
                }
                max = length_of_last_char_A_of_B[A_index][B_index] > max ? length_of_last_char_A_of_B[A_index][B_index] : max;
            }
        }

        // clear the 2-d array
        for(A_index = 0; A_index < A_end; A_index++) {
            delete []length_of_last_char_A_of_B[A_index];
        }
        delete []length_of_last_char_A_of_B;

        return max;
    }
};

时间复杂度:O(n^2)

猜你喜欢

转载自blog.csdn.net/m0_37576233/article/details/78448930