leetcode 718. 最长重复子数组

    技术2022-07-10  144

    leetcode 718. 最长重复子数组

    题目详情

    题目链接 给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。

    示例 1: 输入: A: [1,2,3,2,1] B: [3,2,1,4,7] 输出: 3 解释: 长度最长的公共子数组是 [3, 2, 1]。

    说明:

    1 <= len(A), len(B) <= 10000 <= A[i], B[i] < 100

    我的代码

    class Solution { public: int findLength(vector<int>& A, vector<int>& B) { int aLen = A.size(), bLen = B.size(); set<int> bSet(B.begin(), B.end()); int res = 0; for (int i = 0; i < aLen - res; ++i) { if (bSet.count(A[i]) == 0) { continue; } for (int j = 0; j < bLen - res; ++j) { if (A[i] == B[j]) { int ans = 1; for (int ii = i + 1, jj = j + 1; (ii < aLen) && (jj < bLen); ++ii, ++jj) { if (A[ii] != B[jj]) { break; } ++ans; } res = max(res, ans); } } } return res; } };

    我的成绩

    执行结果:通过 执行用时:876 ms, 在所有 C++ 提交中击败了5.00%的用户 内存消耗:11.6 MB, 在所有 C++ 提交中击败了100.00%的用户

    一些想法

    本道题我用得暴力法,在此基础上做了些优化,应该有更好的算法。

    执行用时为 52 ms 的范例

    class Solution { public: int findLength(vector<int>& a, vector<int>& b) { int size1 = a.size(), size2 = b.size(); if (size1 == 0 || size2 == 0) return 0; if (size1 < size2) return findLength(b, a); // b更短一点 vector<unsigned int> hash_a(size1 + 1, 0), hash_b(size2 + 1, 0), power(size2 + 1, 1); // init(hash_a, hash_b, power); for (int i = 1; i <= size1; ++i) hash_a[i] = hash_a[i - 1] * 1331 + a[i - 1]; for (int i = 1; i <= size2; ++i) hash_b[i] = hash_b[i - 1] * 1331 + b[i - 1]; for (int i = 1; i <= size2; ++i) power[i] = power[i - 1] * 1331; int left = 1, right = size2, ans = 0; while (left <= right) { int mid = left + (right - left) / 2; unordered_set<unsigned int> set_a; // init_set_a_with_lenMid(); for (int start = 0; start + mid - 1 < size1; ++start) { unsigned int hash_val = hash_a[start + mid] - hash_a[start] * power[mid]; set_a.insert(hash_val); } bool find = false; for (int start = 0; start + mid - 1 < size2; ++start) { unsigned int hash_val = hash_b[start + mid] - hash_b[start] * power[mid]; if (set_a.count(hash_val)) { find = true; break; } } if (find) { left = mid + 1; ans = max(ans, mid); } else { right = mid - 1; } } return ans; } };

    思考

    没看懂范例,建议参考官方解答

    Processed: 0.011, SQL: 9