
之前美区 TikTok 被封,泼天流量给到了海外小红书。
这次川普搞"对等关税",泼天流量给到了海外淘宝。
由于这次"对等关税",祸害的不止是美国人民,影响面覆盖全球,因此这波还不只是局部的(美)国内流量,而是全球流量 🤣🤣
截至目前,淘宝已经在 16 个国家 App 下载榜上排名第一,在 123 个国家中进入前十榜单。
更具体的数据,4 月 12 日,淘宝 App 海外下载量仅 10.4W,而到了 4 月 15 日,下载量飙升至 32.6W,环比增长 222%。其中 iOS 平台,北美地区下载量环比增长了 483%,欧洲环比增长 439%。
大量海外消费者涌入淘宝,目的都是为了"囤货"。
川普带来的"巨大不确定性",不仅金融市场怕,普通老百姓也怕。
如今除中国以外,绝大多数国家的老百姓,都或多或少地在做准备,以迎接这种"不确定性"。
对于美国人民来说,这种担心尤为严重。既担心"90 天谈判期"结束后物价暴涨,更担心"800 美元个人小包豁免关税政策"被突然关闭。
大多数人都"囤货",所带来的后果,除了老百姓的家庭现金流被占用以外,突如其来的"供不应求"也会导致物价上涨,所以哪怕"对等关税"还没正式生效,但恶劣的影响就已经先行了。
或许川普也知道所谓的"对等关税"不可能长期执行,于是设定了 90 天的谈判期,以此作为筹码,与其他贸易伙伴进行谈判,目的只是多拿点"好处"。但"川普悖论"背后这招看似合理的"缓兵之计",最终还是让老百姓付出了实际代价。
对此,你怎么看?看完今天的正能量唠嗑内容,有没有觉得幸福感高了一些?欢迎评论区交流。
...
回归主题。
来一道和「阿里 - 校招」相关的算法题。
平台:LeetCode
题号:678
给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。
有效字符串具有如下规则:
( 必须有相应的右括号 )。) 必须有相应的左括号 ( 。( 必须在对应的右括号之前 )。) ,或单个左括号 ( ,或一个空字符串。示例 1:
输入: "()"
输出: True
示例 2:
输入: "(*)"
输出: True
示例 3:
输入: "(*))"
输出: True
注意:
范围内。
定义
为考虑前
个字符(字符下标从
开始),能否与
个右括号形成合法括号序列。
起始时只有
为 true,最终答案为
。
不失一般性的考虑
该如何转移:
( : 如果 为 true,必然有
为 true,反之亦然。即有
;
) : 如果 为 true,必然有
为 true,反之亦然。即有
;
* : 根据 * 代指的符号不同,分为三种情况,只有有一种情况为 true 即可。即有 。
Java 代码:
class Solution {
public boolean checkValidString(String s) {
int n = s.length();
boolean[][] f = newboolean[n + 1][n + 1];
f[0][0] = true;
for (int i = 1; i <= n; i++) {
char c = s.charAt(i - 1);
for (int j = 0; j <= i; j++) {
if (c == '(') {
if (j - 1 >= 0) f[i][j] = f[i - 1][j - 1];
} elseif (c == ')') {
if (j + 1 <= i) f[i][j] = f[i - 1][j + 1];
} else {
f[i][j] = f[i - 1][j];
if (j - 1 >= 0) f[i][j] |= f[i - 1][j - 1];
if (j + 1 <= i) f[i][j] |= f[i - 1][j + 1];
}
}
}
return f[n][0];
}
}
C++ 代码:
class Solution {
public:
bool checkValidString(string s) {
int n = s.size();
vector<vector<bool>> f(n + 1, vector<bool>(n + 1, false));
f[0][0] = true;
for (int i = 1; i <= n; i++) {
char c = s[i - 1];
for (int j = 0; j <= i; j++) {
if (c == '(') {
if (j >= 1) f[i][j] = f[i - 1][j - 1];
} elseif (c == ')') {
if (j + 1 <= i) f[i][j] = f[i - 1][j + 1];
} else {
f[i][j] = f[i - 1][j];
if (j - 1 >= 0) f[i][j] = f[i][j] || f[i - 1][j - 1];
if (j + 1 <= i) f[i][j] = f[i][j] || f[i - 1][j + 1];
}
}
}
return f[n][0];
}
};
Python 代码:
class Solution:
def checkValidString(self, s: str) -> bool:
n = len(s)
f = [[False] * (n + 1) for _ in range(n + 1)]
f[0][0] = True
for i in range(1, n + 1):
c = s[i - 1]
for j in range(i + 1):
if c == '(':
if j >= 1:
f[i][j] = f[i-1][j-1]
elif c == ')':
if j + 1 <= i:
f[i][j] = f[i-1][j+1]
else:
f[i][j] = f[i-1][j]
if j - 1 >= 0:
f[i][j] |= f[i-1][j-1]
if j + 1 <= i:
f[i][j] |= f[i-1][j+1]
return f[n][0]
通过解法一,我们进一步发现,对于某个
而言(即动规数组中的某一行),值为 true 的必然为连续一段。
由于存在可变化的 * 符号,因此考虑在考虑前
个字符,其能与消耗的左括号的数量具有明确的「上界与下界」。且当前上界与下界的变化,仅取决于「当前为何种字符」,以及「处理上一个字符时上界与下界为多少」。
但直接记录所能消耗的左括号上限和下限需要处理较多的边界问题。
我们可以使用与(题解)301. 删除无效的括号 类似的思路:
令左括号的得分为
;右括号的得分为
。那么对于合法的方案而言,必定满足最终得分为
。
同时由于本题存在 *,因此我们需要记录得分的区间区间是多少,而不仅是一个具体的得分。
具体的,使用两个变量 l 和 r 分别表示「最低得分」和「最高得分」。
根据当前处理到的字符进行分情况讨论:
( : l 和 r 同时加一;) : l 和 r 同时减一;* : 如果 * 代指成 ( 的话,l 和 r 都进行加一;如果 * 代指成 ) 的话,l 和 r 都进行减一;如果 * 不变的话,l 和 r 均不发生变化。因此总的 l 的变化为减一,总的 r 的变化为加一。需要注意的是,在匹配过程中如果 l 为负数,需要重置为
,因为如果当前序列本身为不合法括号序列的话,增加 ( 必然还是不合法。同时,当出现 l > r 说明上界为负数,即右括号过多,必然为非合法方案,返回 false。
Java 代码:
class Solution {
public boolean checkValidString(String s) {
int l = 0, r = 0;
for (char c : s.toCharArray()) {
if (c == '(') {
l++; r++;
} elseif (c == ')') {
l--; r--;
} else {
l--; r++;
}
l = Math.max(l, 0);
if (l > r) returnfalse;
}
return l == 0;
}
}
C++ 代码:
class Solution {
public:
bool checkValidString(string s) {
int l = 0, r = 0;
for (int i = 0; i < s.size(); i++) {
char c = s[i];
if (c == '(') {
l++; r++;
} elseif (c == ')') {
l--; r--;
} else {
l--; r++;
}
l = max(l, 0);
if (l > r) returnfalse;
}
return l == 0;
}
};
Python 代码:
class Solution:
def checkValidString(self, s: str) -> bool:
l, r = 0, 0
for c in s:
if c == '(':
l, r = l + 1, r + 1
elif c == ')':
l, r = l - 1, r - 1
else:
l, r = l - 1, r + 1
l = max(l, 0)
if l > r:
return False
return l == 0