左移注意 1ll
将++数字1声明为 long long (64位长整型)++,做左移( << )操作时用 1ll
避免32位 int 类型的溢出问题
质数筛的思想与推广
其实就是一种**++预处理分组 避免重复计算与选择++**
抽象出可复用的 讨论计算代码~回文的处理
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
++s[i]==t[j] 时, f[i][j] = f[i-1][j+1] + 1++
lcr156
++前序bfs把二叉树转成带null标记的字符串++
再按层序规则把字符串还原成二叉树,还会删掉末尾多余的null标记
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root)
{
if(root == nullptr) return "";
string res;
queue<TreeNode*> order;
order.push(root);
while (!order.empty())
{
int size = order.size();
while(size--)
{
auto top = order.front();
order.pop();
if(top == nullptr)
res+="null,";
else
{
res+=to_string(top->val)+",";
order.push(top->left);
order.push(top->right);
}
}
}
res.erase(res.size()-1);
while (res.size()>=5&&res.substr(res.size()-5,5)==",null")
++res.erase(res.size()-5,5);
return res;++
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
TreeNode* head = new TreeNode();
if(data.size() == 0)
return nullptr;
vector<string> value;
int begin = 0 ,length = 0;
string value_part;
for(int i = 0;i<data.size();i++){
if(data[i] == ','){
value.push_back(data.substr(begin,length));
begin = i+1;
length = 0;
}
else
length++;
}
value.push_back(data.substr(begin,length));
head->val = stoi(value[0]);
queue<TreeNode*> tree;
tree.push(head);
int pos = 1;
while (pos<value.size()){
TreeNode *p = tree.front();
tree.pop();
if(value[pos]!="null") {
p->left = new TreeNode(stoi(value[pos]));
tree.push(p->left);
}
pos++;
if(pos<value.size()&&value[pos]!="null") {
p->right = new TreeNode(stoi(value[pos]));
tree.push(p->right);
}
pos++;
}
return head;
}
};
lc3504
枚举回文中心+dp
dp匹配双字符串公共子串长度
中心扩展法找回文子串
计算两类字符串组合下的最长回文串长度
确定dp状态:用 f[i+1][j] 表示 s 前 i 个字符与 t 前 j 个字符匹配时的连续公共子串长度;
推导状态转移:
++s[i]==t[j] 时, f[i][j] = f[i-1][j+1] + 1++
否则保持默认0;
初始化dp数组:二维数组 f 和一维数组 mx 均默认初始化为0
遍历顺序:
++for (int i = 0; i < n; i++)++
++for (int j = 0; j < m; j++)++
按 s 的字符顺序外层循环,内层遍历 t 的字符,保证状态依赖的前置值已计算;
- 获取最终结果:先通过 mx 取 f ++每行最大值得到等长匹配的回文长度++,再结合中心扩展法的回文串长度,取两者最大值作为结果
class Solution {
public:
int calc(string& s, string& t) {
int n = s.size(), m = t.size();
vector<int> mx(n + 1);
vector f(n + 1, vector<int>(m + 1));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
++if (s[i] == t[j]) {
f[i + 1][j] = f[i][j + 1] + 1;++
}
}
++mx[i + 1] = ranges::max(f[i + 1]);++
}
++int ans = ranges::max(mx) * 2;++// |x| = |y| 的情况
// 计算 |x| > |y| 的情况,中心扩展法
for (int i = 0; i < 2 * n - 1; i++) {
int l = i / 2, r = (i + 1) / 2;
while (l >= 0 && r < n && s[l] == s[r]) {
l--;
r++;
}
if (l + 1 <= r - 1) {
// s[l+1] 到 s[r-1] 是非空回文串
++ans = max(ans, r - l - 1 + mx[l + 1] * 2);++
}
}
return ans;
}
int longestPalindrome(string s, string t) {
string rev_s = s, rev_t = t;
ranges::reverse(rev_s);
ranges::reverse(rev_t);
return max(calc(s, t), calc(rev_t, rev_s));
//抽象出可复用的 讨论计算代码~
}
};