#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
struct ListNode {
int val;
ListNode *next = nullptr;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
void print(const vector<vector<string>>v)
{
for(auto str:v)
{
for(auto s:str)
{
cout << s << " ";
}
cout << endl;
}
}
void print(ListNode* head)
{
while(head != nullptr)
{
cout << head->val << endl;
head = head->next;
}
}
bool isPalindrome(string s)
{
int left = 0, right = s.size() - 1;
while(left < right)
{
if(s[left] == s[right])
{
++left;
--right;
}
else
{
return false;
}
}
return true;
}
bool isValid(string s, int left,int right)
{
while(left < right)
{
if(s[left] == s[right])
{
++left;
--right;
}
else
{
return false;
}
}
return true;
}
bool isPalindromeII(string s)
{
int left = 0, right = s.size() - 1;
while(left <right && s[left] == s[right])
{
++left;
--right;
}
if(left >= right)return true;
if(isValid(s,left,right-1) || isValid(s,left+1,right)) return true;
else
return false;
}
bool isPalindrome(int x)
{
if(x < 0 ||(x > 0 && (x % 10) == 0))return false;
int reverse = 0;
while(x > reverse)
{
reverse = reverse * 10 + x % 10;
x /= 10;
}
return (x == reverse || x == reverse / 10);
}
ListNode* reverse(ListNode* head)
{
ListNode* pre,*phead,*temp;
phead = head; //将phead指向链表头,做游标使用
pre = nullptr; //pre为头指针之前的节点
while(phead != nullptr){
temp = pre;
pre = phead;
phead = phead->next;
pre->next = temp; //pre接到之前的节点
}
return pre;
}
ListNode* endOfFirstHalf(ListNode* head)
{
ListNode* fast = head;
ListNode* slow = head;
while(fast->next != nullptr && fast->next->next != nullptr)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
bool isPalindrome(ListNode* head) {
if(nullptr == head)return true;
ListNode* firstHalfEnd = endOfFirstHalf(head);
ListNode* secondHalfSt = reverse((firstHalfEnd->next));
ListNode* p1 = head;
ListNode* p2 = secondHalfSt;
bool res = true;
while(res && p2 != nullptr)
{
if(p1->val != p2->val)res = false;
p1 = p1->next;
p2 = p2->next;
}
firstHalfEnd->next = reverse(secondHalfSt);
return res;
}
void help(string s, int start, int offset, string& res)
{
int left = start, right = left + offset;
while(left >= 0 && right < s.size() && s[left] == s[right])
{
--left;
++right;
}
string cur = s.substr(left+1,right-1);
if(cur.size() > res.size())
{
res = cur;
}
return ;
}
string longestPalindrome_center(string s) {
string res;
for(int i = 0; i < s.size(); ++i)
{
help(s,i,0,res);
help(s,i,1,res);
}
return res;
}
string longestPalindrome(string s) {
int n = s.size();
vector<vector<bool>>dp(n,vector<bool>(n,false));
int start = 0, end = 0;
for(int i = n - 1; i >= 0; --i)
{
for(int j = i ; j < n; ++j)
{
if(s[i] == s[j] && (j - i <= 2 || dp[i+1][j-1]))
{
if(end - start < j - i)
{
end = j;
start = i;
}
dp[i][j] = true;
}
}
}
return s.substr(start,end - start +1);
}
int countSubString(const string s)
{
int n = s.size(), res = 0;
vector<vector<bool>>dp(n,vector<bool>(n,false));
for(int i = n - 1; i >= 0; --i)
{
for(int j = i; j < n; ++j)
{
if(s[i] == s[j] && ((j - i)< 2 ||dp[i+1][j-1]))
{
dp[i][j] = true;
}
if(dp[i][j])++res;
}
}
return res;
}
int lcs(string s,string s_v)
{
int m = s.size(), n = s_v.size();
vector<vector<int>>dp(m + 1,vector<int>(n + 1,0));
for(int i = 0; i < m; ++i)
{
for(int j = 0;j < n; ++j)
{
if(s[i] == s_v[j])
{
dp[i+1][j+1] = dp[i][j] + 1;
}
else
{
dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
}
}
}
return dp[m][n];
}
int longestPalindromeSubseq(string s) {
string s_v = s;
reverse(s_v.begin(),s_v.end());
return lcs(s,s_v);
}
void backtrack(vector<vector<string>>&res,vector<string>&path,const vector<vector<bool>>&dp,string s,int pos)
{
if(pos == s.size())
{
res.push_back(path);
return;
}
for(int i = pos; i < s.size(); ++i)
{
if(dp[pos][i])
{
int len = i - pos + 1;
path.push_back(s.substr(pos,len));
backtrack(res,path,dp,s,i+1);
path.pop_back();
}
}
}
vector<vector<string>> partition(string s) {
int n = s.size();
vector<vector<bool>>dp(n,vector<bool>(n,false));
for (int i = n - 1; i >= 0; --i)
{
for (int j = i; j < n; ++j)
{
if (s[i] == s[j] && (j - i <= 2 || dp[i + 1][j - 1]))
{
dp[i][j] = true;
}
}
}
vector<vector<string>>res;
vector<string>path;
backtrack(res,path,dp,s,0);
return res;
}
int main()
{
string s = "abccba";
cout << isPalindrome(s) << endl;
//LeetCode680
s = "abca";
cout << isPalindromeII(s) << endl;
//LeetCode9
int x = 121;
cout << isPalindrome(x) << endl;
//LeetCode234
ListNode n0(1);
ListNode n1(3);
ListNode n2(3);
//ListNode n3(1);
//n0.next = &n1;
//n1.next = &n2;
//n2.next = &n3;
//cout << isPalindrome(&n0) << endl;
////LeetCode5
//s = "babad";
//cout << longestPalindrome(s) << endl;
//cout << longestPalindrome_center(s) << endl;
//LeetCode647
//s = "abcc";
//cout <<countSubString(s) <<endl;
//LeetCode516
/* s = "bbbab";
cout << s << endl;
cout << longestPalindromeSubseq(s) << endl;*/
//
//LeetCode131
s = "aab";
print(partition(s));
return 0;
}