diff --git a/cpp/2305/LC230511.cpp b/cpp/2305/LC230511.cpp new file mode 100644 index 0000000..4322e56 --- /dev/null +++ b/cpp/2305/LC230511.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include + +/** + * 1035. Uncrossed Lines + * + * You are given two integer arrays nums1 and nums2. We write the integers of nums1 and nums2 (in the order they are given) on two separate horizontal lines. + * + * We may draw connecting lines: a straight line connecting two numbers nums1[i] and nums2[j] such that: + * + * nums1[i] == nums2[j], and + * the line we draw does not intersect any other connecting (non-horizontal) line. + * Note that a connecting line cannot intersect even at the endpoints (i.e., each number can only belong to one connecting line). + * + * Return the maximum number of connecting lines we can draw in this way. + */ + +class LC230511 { +public: + using CVIR = const std::vector&; + static int maxUncrossedLines(CVIR, CVIR) noexcept; +}; + +int LC230511::maxUncrossedLines(const std::vector& nums1, const std::vector& nums2) noexcept { + const int p = nums1.size(), q = nums2.size(); + std::unordered_map> m[2]; + for (int i = 0; i < p; ++i) + m[0][nums1[i]].insert(i); + for (int i = 0; i < q; ++i) + m[1][nums2[i]].insert(i); + + std::int16_t dp[512][512]; + std::memset(dp, -1, sizeof dp); + std::function solve = [&](int pos_1, int pos_2) { + auto& ans = dp[pos_1][pos_2]; + if (ans >= 0) + return ans; + if (pos_1 >= p || pos_2 >= q) + return ans = 0; + ans = std::max(solve(pos_1 + 1, pos_2), solve(pos_1, pos_2 + 1)); + + // Select in nums1 + auto& n1p1_in_n2 = m[1][nums1[pos_1]]; + if (auto it = n1p1_in_n2.lower_bound(pos_2); it != n1p1_in_n2.end()) + ans = std::max(ans, std::int16_t(solve(pos_1 + 1, *it + 1) + 1)); + + // Select in nums2 + auto& n2p2_in_n1 = m[0][nums2[pos_2]]; + if (auto it = n2p2_in_n1.lower_bound(pos_1); it != n2p2_in_n1.end()) + ans = std::max(ans, std::int16_t(solve(*it + 1, pos_2 + 1) + 1)); + + return ans; + }; + + return solve(0, 0); +} + +using Solution = LC230511; diff --git a/cpp/2305/defs.h b/cpp/2305/defs.h index d6e44ee..d15923a 100644 --- a/cpp/2305/defs.h +++ b/cpp/2305/defs.h @@ -118,4 +118,10 @@ public: static bool queryString(const std::string& s, int n) noexcept; }; +class LC230511 { +public: + using CVIR = const std::vector&; + static int maxUncrossedLines(CVIR, CVIR) noexcept; +}; + #endif //LEETCODE_CPP_DEFS_H diff --git a/cpp/2305/main.cpp b/cpp/2305/main.cpp index 6d2c9fc..61c2f20 100644 --- a/cpp/2305/main.cpp +++ b/cpp/2305/main.cpp @@ -14,6 +14,6 @@ std::ostream& operator<<(std::ostream& os, const std::vector& x) noexcept { } int main() { - std::cout << LC230511CN::queryString("0110", 3); + std::cout << LC230511::maxUncrossedLines({1,3,7,1,7,5},{1,9,2,5,1}); return 0; }