add: 220105 [Not a good example!]

This commit is contained in:
Lam Haoyin 2022-01-06 00:16:25 +08:00
parent ffbbafc851
commit cc55911d89
No known key found for this signature in database
GPG Key ID: 8C089CB1A2B7544F
2 changed files with 136 additions and 1 deletions

135
2201/220105.cpp Normal file
View File

@ -0,0 +1,135 @@
#include <vector>
#include <string>
#include <set>
#include <chrono>
#include <iostream>
/**
* 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<std::vector<std::string>> generate(int cnt, char ch, std::vector<std::vector<std::string>>* const dpp) {
if (dpp[cnt].size()) return dpp[cnt];
if (cnt == 1) {
return dpp[1] = {{std::string(1, ch)}};
}
std::vector<std::vector<std::string>> 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<std::vector<std::string>> getPartition(int L, int R) {
// Partition of [L, i], [i + 1, R]
std::vector<std::vector<std::string>> ret;
if (sameTo[L] == sameTo[R]) {
int cnt = R - L + 1;
std::vector<std::vector<std::string>> 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<std::vector<std::string>> 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<std::vector<std::string>> 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<std::chrono::milliseconds>(t3 - t2).count() << "ms" << std::endl;
return ret;
}
};
int main() {
Solution solver;
auto ans = solver.partition("aaaaaaaaaaaaaaaa");
std::cout << ans.size();
return 0;
}

View File

@ -3,4 +3,4 @@ PROJECT(2201)
SET(CMAKE_CXX_STANDARD 23) SET(CMAKE_CXX_STANDARD 23)
ADD_EXECUTABLE(2201 220105-CN.cpp) ADD_EXECUTABLE(2201 220105.cpp)