tt -> xhs
这两天,全球互联网最大的乐子新闻,是大量的 TikTok(简称 tt)用户开始涌向 xhs。
转折发生在上周五,北京时间 2025-01-11。
虽然此前当选总统川普对 tt 表示过支持,甚至在竞选时期发誓要拯救该应用。但这一建议,在上周五举行的司法部和 tt 的口头辩论中被正式驳回,法官仍然倾向于封禁。
这意味着,如果没有其他意外,tt 将会在 2025-01-19 被正式封禁。
但,川普的正式上任时间是 2025-01-20。
不可否认,一旦新旧政府交接完成,对于 tt 来说,局面会完全不同。
但需要考虑的,要解禁可不是一嘴的事情,想要解禁仍然需要走参议两会投票的流程,最后环节才是总统签字。这个流程快则几个月,慢则一两年。
所以什么「1-19 禁,1-20 解,权当放假」的"爽文"剧情,就不要幻想了。
而且更加致命的是,这是川普(79 岁)的最后一任总统,他不会再需要 tt 来竞选。
上任后,他还有一个曾经承诺 24 小时内解决的大问题要处理,他会有多大的动力来推进 tt 解封?目前还不得而知。
好了,说回 tt -> xhs 的部分。
其实昨天,就有大量用户从 tt 涌向 xhs,一度让 xhs 在美区成为「社交类」应用的第二名,也是榜单中的唯一一款中文社交媒体。
今天,直接登顶第一了 🤣🤣🤣
要知道,xhs 是没有分国内外版本的,这意味着海外用户会看到大量(源于我们这边)的中文内容(甚至在海外区上架的应用 LOGO 也是中文)。
这对于一个社交类的"重内容"应用来说,使用体验可以说是"毛坯房"级别的。
但这丝毫不影响国内外网友"狭路相逢"般的友好交流 🤣🤣🤣
甚至已经有海外博主在 xhs 开讲,分享如何使用 xhs 的相关技巧,简直不要太离谱 🤣🤣🤣
另外一些机器翻译的现场,也很有意思,一位外国人发了关于学习「麻将中"一条/幺鸡"」的帖子。
但评论区的画风,是这样的:
哈哈哈哈哈,实在绷不住了。
很久没看到这么欢乐的互联网现场,我只能说,希望 xhs 区分海外版的动作能够再慢一些 🤣🤣🤣
对此,你怎么看?是否准备也下载一个 xhs 来看看?(正向循环了属于是
...
回归主题。
来一道和「小红书」相关的算法题。
题目描述
平台:LeetCode
题号:730
给定一个字符串 s,返回 s 中不同的非空「回文子序列」个数。
通过从 s 中删除 个或多个字符来获得子序列。
如果一个字符序列与它反转后的字符序列一致,那么它是「回文字符序列」。
如果有某个 , 满足 != ,则两个序列 a1, a2, ... 和 b1, b2, ... 不同。
注意:结果可能很大,你需要对 取 。
示例 1:
输入:s = 'bccb'
输出:6
解释:6 个不同的非空回文子字符序列分别为:'b', 'c', 'bb', 'cc', 'bcb', 'bccb'。
注意:'bcb' 虽然出现两次但仅计数一次。
示例 2:
输入:s = 'abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba'
输出:104860361
解释:共有 3104860382 个不同的非空回文子序列,104860361 对 109 + 7 取模后的值。
提示:
s[i]仅包含'a','b','c'或'd'
区间 DP
往长度较少的回文串两端添加字符,可能组成新的长度大的回文串,容易想到「区间 DP」,同时 s 仅由 类小写字母组成,也是一个切入点。
根据区间 DP 的一般思路,定义 为考虑字符串 s 中的 范围内回文子序列的个数,最终答案为 。
不失一般性考虑 该如何转移,通过枚举 abcd 作为回文方案「边缘字符」来进行统计,即分别统计各类字符作为「边缘字符」时对 的贡献,此类统计方式天生不存在重复性问题。
假设当前枚举到的字符为 :
- 若 中没有字符 ,则字符 对 贡献为 ,跳过;
- 若 中存在字符 ,根据字符 在范围 中「最小下标」和「最大下标」进行分情况讨论,假设字符 在 中「最靠左」的位置为 ,「最靠右」的位置为 :
- 当 时,此时字符 对 的贡献为 ,即
k本身; - 当 时,说明字符 中间不存在任何字符,此时字符 对 的贡献为 ,包括
k和kk两种回文方案; - 其余情况,可根据已算得的「小区间回文方案」进行延伸(两段分别补充位于 和 的字符 ),得到新的大区间方案,此部分对 的贡献是 ,另外还有
k和kk两种回文方案,因此总的对答案的贡献为 。
- 当 时,此时字符 对 的贡献为 ,即
统计 中各类字符「最靠左」和「最靠右」的位置,可通过调整枚举方向来实现:从大到小枚举 ,同时维护 L[s[i]-'a'] = i,即可得到「最靠左」的位置;在确定左端点 之后,从小到大枚举右端点 ,同时维护 R[s[j]-'a'] = j,即可得到「最靠右」的位置。
Java 代码:
class Solution {
public int countPalindromicSubsequences(String s) {
char[] cs = s.toCharArray();
int n = cs.length, MOD = (int)1e9+7;
int[][] f = new int[n][n];
int[] L = new int[4], R = new int[4];
Arrays.fill(L, -1);
for (int i = n - 1; i >= 0; i--) {
L[cs[i] - 'a'] = i;
Arrays.fill(R, -1);
for (int j = i; j < n; j++) {
R[cs[j] - 'a'] = j;
for (int k = 0; k < 4; k++) {
if (L[k] == -1 || R[k] == -1) continue;
int l = L[k], r = R[k];
if (l == r) f[i][j] = (f[i][j] + 1) % MOD;
else if (l == r - 1) f[i][j] = (f[i][j] + 2) % MOD;
else f[i][j] = (f[i][j] + f[l + 1][r - 1] + 2) % MOD;
}
}
}
return f[0][n - 1];
}
}
C++ 代码:
class Solution {
public:
int countPalindromicSubsequences(string s) {
int n = s.length(), MOD = 1e9 + 7;
vector<vector<int>> f(n, vector<int>(n, 0));
vector<int> L(4, -1), R(4, -1);
for (int i = n - 1; i >= 0; i--) {
L[s[i] - 'a'] = i;
fill(R.begin(), R.end(), -1);
for (int j = i; j < n; j++) {
R[s[j] - 'a'] = j;
for (int k = 0; k < 4; k++) {
if (L[k] == -1 || R[k] == -1) continue;
int l = L[k], r = R[k];
if (l == r) f[i][j] = (f[i][j] + 1) % MOD;
else if (l == r - 1) f[i][j] = (f[i][j] + 2) % MOD;
else f[i][j] = (f[i][j] + f[l + 1][r - 1] + 2) % MOD;
}
}
}
return f[0][n - 1];
}
};
Python 代码:
class Solution:
def countPalindromicSubsequences(self, s: str) -> int:
n, MOD = len(s), 10**9 + 7
f = [[0] * n for _ in range(n)]
L, R = [-1] * 4, [-1] * 4
for i in range(n - 1, -1, -1):
L[ord(s[i]) - ord('a')] = i
R = [-1] * 4
for j in range(i, n):
R[ord(s[j]) - ord('a')] = j
for k in range(4):
if L[k] == -1 or R[k] == -1: continue
l, r = L[k], R[k]
if l == r: f[i][j] = (f[i][j] + 1) % MOD
elif l == r - 1: f[i][j] = (f[i][j] + 2) % MOD
else: f[i][j] = (f[i][j] + f[l + 1][r - 1] + 2) % MOD
return f[0][n - 1]
TypeScript 代码:
function countPalindromicSubsequences(s: string): number {
const n = s.length, MOD = 1e9 + 7;
const f = Array.from({ length: n }, () => Array(n).fill(0));
const L = new Array(4).fill(-1), R = new Array(4).fill(-1);
for (let i = n - 1; i >= 0; i--) {
L[s.charCodeAt(i) - 'a'.charCodeAt(0)] = i;
R.fill(-1);
for (let j = i; j < n; j++) {
R[s.charCodeAt(j) - 'a'.charCodeAt(0)] = j;
for (let k = 0; k < 4; k++) {
if (L[k] === -1 || R[k] === -1) continue;
const l = L[k], r = R[k];
if (l === r) f[i][j] = (f[i][j] + 1) % MOD;
else if (l === r - 1) f[i][j] = (f[i][j] + 2) % MOD;
else f[i][j] = (f[i][j] + f[l + 1][r - 1] + 2) % MOD;
}
}
}
return f[0][n - 1];
};
- 时间复杂度:,其中 为字符集大小
- 空间复杂度: