宇树科技
距离宇树科技上市已经半个月,仅仅 12 个交易日,股价就从首日的 1100 元(对应市值约 4400 亿)跌到了现在的 550 元(市值约 2200 亿),跌幅达到 50%。
这可是「具身智能」领域的世界头号玩家。由此可见,同样都是搞科技,管你技术有多新,要么足够能赚钱,要么故事足够性感,否则资本只炒短线。
其实上市第二天,我就给过结论:没中就别买,尤其是这种大热门。

金融有句著名的话:当股价下跌时,企业呼吸都是错的。随着宇树科技大跌,不少股民被套,于是开始质疑宇树只是一家炒作公司,仅靠上春晚撑起千亿市值,压根没有任何技术。
甚至连「宇树科技抠到离谱,超过 100 元的报销,都要 CEO 本人审批」的鬼故事都来了。

要我说,这就有点偏激了。宇树科技在「硬件自研」和「成本控制」上,不单是中国第一,还是全球第一,领先西大 2 年以上。宇树真正弱在「算法」上,它的 AI 算法/具身大模型,不仅落后于西大的对手(特斯拉、Figure AI),在国内也不是绝对的第一。
只看人形机器人,今年上半年,智元机器人以约 8400 台出货量、44% 的全球份额超越宇树,登顶第一,两家合计占据全球约 75% 的市场份额。但如果看四足机器人,宇树科技仍然是当之无愧的全球第一,自己就独占了 50%~60% 的市场份额。
所以上市半月腰斩,主要还是 A 股炒作风气所致。好技术不等于好生意,好公司也不等于好股票。现在的纯 AI 持续有热钱炒作,是因为大家都看到了提效案例,尤其是编程开发领域,现在几乎都是零人工了。未来还有多少领域会被 AI 颠覆,说不准,但肯定会有,只是多与少的问题。
但现在的具身智能,进医院做手术吧,精度不够、稳定性不够;进厂打螺丝吧,费用太高,没有实质的替代意义。或许等到哪一天具身智能迎来奇点,才是宇树一飞冲天的时候。现在的 2000 亿市值、380 倍 TTM(滚动市盈率),你要问我,我是觉得下方还有很大空间 😂
题目描述
平台: LeetCode
题号:899
给定一个字符串 s 和一个整数 k。
你可以从 s 的前 k 个字母中选择一个,并把它加到字符串的末尾。
返回在应用上述步骤的任意数量的移动后,字典上最小的字符串。
示例 1:
输入:s = "cba", k = 1
输出:"acb"
解释:
在第一步中,我们将第一个字符("c")移动到最后,获得字符串 "bac"。
在第二步中,我们将第一个字符("b")移动到最后,获得最终结果 "acb"。
示例 2:
输入:s = "baaca", k = 3
输出:"aaabc"
解释:
在第一步中,我们将第一个字符("b")移动到最后,获得字符串 "aacab"。
在第二步中,我们将第三个字符("c")移动到最后,获得最终结果 "aaabc"。
提示:
1 <= k <= s.length <= 1000
s 只由小写字母组成。
最小表示法
当 $k > 1$ 时,我们能够构造出任意的字符串方案,因此可以直接通过对字符串排序来得到答案,复杂度为 $O(n \log n)$。
当 $k = 1$ 时,我们共有 $n$ 种候选方案(将字符串 s 看作一个首尾相接的循环字符串,共有 $n$ 个起点可枚举),枚举过程中需要与当前最优方案进行比较,比较复杂度为 $O(n)$,因此整体复杂度为 $O(n^2)$。
上述做法已经可以通过本题,可以看出瓶颈在于对 $O(n^2)$ 的处理。
实际上,对于给定字符串 s,求其循环同构的所有方案中字典序最小的方案,可以使用「最小表示法」来做,复杂度为 $O(n)$。
最小表示法将「方案比较」与「构造更优方案」进行结合:假设我们当前有两字符串 a 和 b 需要比较,它们均为原串 s 的循环同构具体方案。假设 a 和 b 分别对应原串下标为 i 和 j 的具体方案,且假设两字符串前 $k$ 个字符均相同。
当两字符串第一个不同的字符大小关系为 $s[(i+k)\%n] > s[(j+k)\%n]$ 时,可以发现在下标范围 $[i, i+k]$ 作为起点的新方案 a' 必然不会是最优方案,即必然存在下标范围 $[j, j+k]$ 作为起点的新方案 b' 比其更优。因此我们可以直接从 $i+k+1$ 位置构造新的更优方案,并与 b 再次比较。而 $s[(i+k)\%n] < s[(j+k)\%n]$ 的分析同理。
更为直白的表述为:分别从 i 和 j 作为起点的字符串 a 和 b,其前 $k$ 个字符相同,而当 $s[(i+k)\%n] > s[(j+k)\%n]$ 时,我们可以明确「以 $i+p$ 为起点的字符串」必不可能比「以 $j+p$ 为起点的字符串」更优,其中 $0 \le p \le k$。
Java 代码:
class Solution {
public String orderlyQueue(String s, int _k) {
char[] cs = s.toCharArray();
if (_k == 1) {
int i = 0, j = 1, k = 0, n = cs.length;
while (i < n && j < n && k < n) {
char a = cs[(i + k) % n], b = cs[(j + k) % n];
if (a == b) k++;
else {
if (a > b) i += k + 1;
else j += k + 1;
if (i == j) i++;
k = 0;
}
}
i = Math.min(i, j);
return s.substring(i) + s.substring(0, i);
} else {
Arrays.sort(cs);
return String.valueOf(cs);
}
}
}
C++ 代码:
class Solution {
public:
string orderlyQueue(string s, int _k) {
if (_k == 1) {
int i = 0, j = 1, k = 0, n = s.length();
while (i < n && j < n && k < n) {
char a = s[(i + k) % n], b = s[(j + k) % n];
if (a == b) k++;
else {
if (a > b) i += k + 1;
else j += k + 1;
if (i == j) i++;
k = 0;
}
}
i = min(i, j);
return s.substr(i) + s.substr(0, i);
} else {
char* cs = new char[s.length()];
copy(s.begin(), s.end(), cs);
sort(cs, cs + s.length());
string sortedString(cs, s.length());
return sortedString;
}
}
};
Python 代码:
class Solution:
def orderlyQueue(self, s: str, _k: int) -> str:
if _k == 1:
i, j, k, n = 0, 1, 0, len(s)
while i < n and j < n and k < n:
a, b = s[(i + k) % n], s[(j + k) % n]
if a == b:
k += 1
else:
if a > b:
i += k + 1
else:
j += k + 1
if i == j:
i += 1
k = 0
i = min(i, j)
return s[i:] + s[:i]
else:
return ''.join(sorted(s))
TypeScript 代码:
function orderlyQueue(s: string, _k: number): string {
if (_k == 1) {
let i = 0, j = 1, k = 0, n = s.length
while (i < n && j < n && k < n) {
const a = s[(i + k) % n], b = s[(j + k) % n]
if (a == b) k++;
else {
if (a > b) i += k + 1
else j += k + 1
if (i == j) i++
k = 0
}
}
i = Math.min(i, j)
return s.substring(i) + s.substring(0, i)
} else {
return [...s].sort().join('');
}
};
复杂度:
- 时间复杂度:当 $k = 1$ 时,复杂度为 $O(n)$;当 $k > 1$ 时,复杂度为 $O(n \log n)$。
- 空间复杂度:当 $k > 1$ 时,需要使用额外的排序空间 $O(n)$。
这类从行业热点切到算法题的杂谈,在云栈社区也常有人讨论。