From cc55911d89f7b4f292e9673577cbd5faeba296e1 Mon Sep 17 00:00:00 2001 From: Lam Haoyin Date: Thu, 6 Jan 2022 00:16:25 +0800 Subject: [PATCH] add: 220105 [Not a good example!] --- 2201/220105.cpp | 135 ++++++++++++++++++++++++++++++++++++++++++++ 2201/CMakeLists.txt | 2 +- 2 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 2201/220105.cpp diff --git a/2201/220105.cpp b/2201/220105.cpp new file mode 100644 index 0000000..ceb652d --- /dev/null +++ b/2201/220105.cpp @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include + +/** + * 131. Palindrome Partitioning + * Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. + * + * A palindrome string is a string that reads the same backward as forward. + */ + +class Solution { +private: + // isPalindromeS[L][R] -> 0: not visited, 1: is, -1: is not a palindrome. + int isPalindromeS[17][17]{}; + int hasPalindromeS[17][17]{}; + int sameTo[17]{}; + int strLen = -1; + const char* str = nullptr; + + /** + * whether str[L..R], ranged [L, R], is a palindrome. + * @param L Index of the left of the range, included. + * @param R ditto + * @return -1 -> is not, 1 -> is palindrome. + */ + int isPalindrome(int L, int R) { + if (L > R) return -1; + if (isPalindromeS[L][R]) return isPalindromeS[L][R]; + switch (R - L) { + case 0: + return isPalindromeS[L][R] = 1; + case 1: + return isPalindromeS[L][R] = (str[L] == str[R] ? 1 : -1); + default: + return isPalindromeS[L][R] = (str[L] == str[R] ? isPalindrome(L + 1, R - 1) : -1); + } + } + + int hasPalindrome(int L, int R) { + if (hasPalindromeS[L][R]) return hasPalindromeS[L][R]; + if (L >= R) return hasPalindromeS[L][R] = -1; + if (isPalindrome(L, R)) return 1; + switch (R - L) { + case 1: + return hasPalindromeS[L][R] = isPalindrome(L, R); + default: + return hasPalindromeS[L][R] = (hasPalindrome(L + 1, R) == 1 || hasPalindrome(L, R - 1) == 1 ? 1 : -1); + } + } + + std::vector> generate(int cnt, char ch, std::vector>* const dpp) { + if (dpp[cnt].size()) return dpp[cnt]; + if (cnt == 1) { + return dpp[1] = {{std::string(1, ch)}}; + } + std::vector> ret; + for (int i = 1; i < cnt; ++i) { + auto th = generate(cnt - i, ch, dpp); + for (auto& j : th) { + j.insert(j.begin(), std::string(i, ch)); + } + ret.insert(ret.end(), th.begin(), th.end()); + } + ret.push_back({std::string(cnt, ch)}); + return dpp[cnt] = ret; + } + + // Partition of [L, R] + std::vector> getPartition(int L, int R) { + // Partition of [L, i], [i + 1, R] + std::vector> ret; + if (sameTo[L] == sameTo[R]) { + int cnt = R - L + 1; + std::vector> dpp[cnt+3]; + return generate(cnt, str[L], dpp); + } + if (hasPalindrome(L, R) != 1) { + ret = {{}}; + auto& t = ret[0]; + for (int i = L; i <= R; ++i) { + t.emplace_back(str + i, 1); + } + return ret; + } + if (isPalindrome(L, R) == 1) { + ret.push_back({std::string(str + L, R - L + 1)}); + } + for (int i = L; i < R; ++i) { + auto left = getPartition(L, i); + auto right = getPartition(i + 1, R); + for (const auto& j: left) { + for (const auto& k: right) { + ret.push_back(j); + auto& thisVec = ret.back(); + thisVec.insert(thisVec.end(), k.begin(), k.end()); + } + } + } + std::set> s; + s.insert(ret.begin(), ret.end()); + return {s.begin(), s.end()}; + } + +public: + // Partition of [L, R) is all Cartesian Product of [L, M) and [M, R)'s partition. + std::vector> partition(const std::string& s) { + this->strLen = s.length(); + this->str = s.c_str(); + auto t2 = std::chrono::high_resolution_clock::now(); + + for (int i = 1; i < this->strLen; ++i) { + if (str[i] == str[i - 1]) { + sameTo[i] = sameTo[i - 1]; + } else { + sameTo[i] = i; + } + } + + auto ret = this->getPartition(0, this->strLen - 1); + + auto t3 = std::chrono::high_resolution_clock::now(); + std::cout << std::chrono::duration_cast(t3 - t2).count() << "ms" << std::endl; + return ret; + } +}; + +int main() { + Solution solver; + auto ans = solver.partition("aaaaaaaaaaaaaaaa"); + std::cout << ans.size(); + return 0; +} \ No newline at end of file diff --git a/2201/CMakeLists.txt b/2201/CMakeLists.txt index faf7f39..daff41d 100644 --- a/2201/CMakeLists.txt +++ b/2201/CMakeLists.txt @@ -3,4 +3,4 @@ PROJECT(2201) SET(CMAKE_CXX_STANDARD 23) -ADD_EXECUTABLE(2201 220105-CN.cpp) \ No newline at end of file +ADD_EXECUTABLE(2201 220105.cpp) \ No newline at end of file