Cursor

昨天科技圈最火的事儿,是 SpaceX 与 xAI 联手拿下 Cursor 收购期权。

alt

据 SpaceX 官方披露,这笔交易存在两种走向:

  1. 行权:在 2026 年底以 600 亿美元将 Cursor 收入囊中

  2. 不行权:向 Cursor 支付 100 亿美元合作费

说实话,我已经有很长一段时间没关注过 Cursor 了,它曾经是一个优秀的产品,但目前已经明显落后,跟同类竞品 Claude Code 或 CodeX,差的不是一点。

而且溢价严重,此前 Cursor 的估值只有 290 亿美元,现在马斯克出价 600 亿美元。

如此高的溢价,让我想起来马斯克对推特的收购 🤣🤣🤣

但首富有自己的考虑,就好像当时买推特,更多的是为了买"舆论主场",为将来的超级平台凑齐拼图。

对 Cursor 的收购,或许也是特斯拉在给未来蓝图补充重要一环,不一定是为了 Claude Code 或 CodeX 直面竞争,或许只是为了提高 xAI 在工程化上能力,这对于 SpaceX 的航天业务,也很有帮助。

那么问题来了:抱上首富大腿之后,你看好 Cursor 未来的发展吗?欢迎在评论区交流。

聊到这里,来一道和「字节跳动」相关的算法题。

题目描述

平台:LeetCode

题号:1438

给你一个整数数组 nums,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit

如果不存在满足条件的子数组,则返回 0。

示例 1:

输入:nums = [8,2,4,7], limit = 4

输出:2 

解释:所有子数组如下:
[8] 最大绝对差 |8-8| = 0 <= 4.
[8,2] 最大绝对差 |8-2| = 6 > 4. 
[8,2,4] 最大绝对差 |8-2| = 6 > 4.
[8,2,4,7] 最大绝对差 |8-2| = 6 > 4.
[2] 最大绝对差 |2-2| = 0 <= 4.
[2,4] 最大绝对差 |2-4| = 2 <= 4.
[2,4,7] 最大绝对差 |2-7| = 5 > 4.
[4] 最大绝对差 |4-4| = 0 <= 4.
[4,7] 最大绝对差 |4-7| = 3 <= 4.
[7] 最大绝对差 |7-7| = 0 <= 4. 
因此,满足题意的最长子数组的长度为 2 。

示例 2:

输入:nums = [10,1,2,4,7,2], limit = 5

输出:4 

解释:满足题意的最长子数组是 [2,4,7,2],其最大绝对差 |2-7| = 5 <= 5 。

示例 3:

输入:nums = [4,2,2,2,4,4,2,2], limit = 0

输出:3

提示:

二分 + 滑动窗口

数据范围是 ,因此只能考虑「对数解法」和「线性解法」。

对数解法很容易想到「二分」。

在给定 limit 的情况下,倘若有「恰好」满足条件的区间长度为 len,必然存在满足条件且长度小于等于 len 的区间,同时必然不存在长度大于 len 且满足条件的区间。

因此长度 len 在数轴中具有「二段性」。

「问题转化为「如何判断 nums 中是否有长度 len 的区间满足绝对值不超过 limit」」

我们可以枚举区间的右端点 r,那么对应的左端点为 r - len + 1,然后使用「单调队列」来保存区间的最大值和最小值。

Java 代码:

class Solution {
    public int longestSubarray(int[] nums, int limit) {
        int n = nums.length;
        int l = 1, r = n;
        while (l < r) {
            int mid = l + r + 1 >> 1;
            if (check(nums, mid, limit))  l = mid;
            else r = mid - 1;
        }
        return r;
    }
    boolean check(int[] nums, int len, int limit) {
        int n = nums.length;
        Deque<Integer> max = new ArrayDeque<>(), min = new ArrayDeque<>();
        for (int r = 0, l = r - len + 1; r < n; r++, l = r - len + 1) {
            if (!max.isEmpty() && max.peekFirst() < l) max.pollFirst();
            while (!max.isEmpty() && nums[r] >= nums[max.peekLast()]) max.pollLast();
            max.addLast(r);
            if (!min.isEmpty() && min.peekFirst() < l) min.pollFirst();
            while (!min.isEmpty() && nums[r] <= nums[min.peekLast()]) min.pollLast();
            min.addLast(r);
            if (l >= 0 && Math.abs(nums[max.peekFirst()] - nums[min.peekFirst()]) <= limit) return true;
        }
        return false;
    }
}

C++ 代码:

class Solution {
public:
    int longestSubarray(vector<int>& nums, int limit) {
        int n = nums.size();
        int l = 1, r = n;
        while (l < r) {
            int mid = l + r + 1 >> 1;
            if (check(nums, mid, limit)) l = mid;
            else r = mid - 1;
        }
        return r;
    }
    bool check(const vector<int>& nums, int len, int limit) {
        int n = nums.size();
        deque<int> max, min;
        for (int r = 0, l = r - len + 1; r < n; r++, l = r - len + 1) {
            if (!max.empty() && max.front() < l) max.pop_front();
            while (!max.empty() && nums[r] >= nums[max.back()]) max.pop_back();
            max.push_back(r);
            if (!min.empty() && min.front() < l) min.pop_front();
            while (!min.empty() && nums[r] <= nums[min.back()]) min.pop_back();
            min.push_back(r);
            if (l >= 0 && abs(nums[max.front()] - nums[min.front()]) <= limit) return true;
        }
        return false;
    }
};
  • 时间复杂度:枚举长度的复杂度为 ,对于每次 check 而言,每个元素最多入队和出队常数次,复杂度为 。整体复杂度为
  • 空间复杂度:
双指针

上述解法我们是在对 len 进行二分,而事实上我们可以直接使用「双指针」解法找到最大值。

始终让右端点 r 右移,当不满足条件时让 l 进行右移。

同时,还是使用「单调队列」保存我们的区间最值,这样我们只需要对数组进行一次扫描即可得到答案。

Java 代码:

class Solution {
    public int longestSubarray(int[] nums, int limit) {
        int n = nums.length, ans = 0;
        Deque<Integer> max = new ArrayDeque<>(), min = new ArrayDeque<>();
        for (int r = 0, l = 0; r < n; r++) {
            while (!max.isEmpty() && nums[r] >= nums[max.peekLast()]) max.pollLast();
            while (!min.isEmpty() && nums[r] <= nums[min.peekLast()]) min.pollLast();
            max.addLast(r);
            min.addLast(r);
            while (Math.abs(nums[max.peekFirst()] - nums[min.peekFirst()]) > limit) {
                l++;
                if (max.peekFirst() < l) max.pollFirst();
                if (min.peekFirst() < l) min.pollFirst();
            }
            ans = Math.max(ans, r - l + 1);
        }
        return ans;
    }
}

C++ 代码:

class Solution {
public:
    int longestSubarray(vector<int>& nums, int limit) {
        int n = nums.size(), ans = 0;
        deque<int> maxDeque, minDeque;
        for (int r = 0, l = 0; r < n; r++) {
            while (!maxDeque.empty() && nums[r] >= nums[maxDeque.back()]) maxDeque.pop_back();
            while (!minDeque.empty() && nums[r] <= nums[minDeque.back()]) minDeque.pop_back();
            maxDeque.push_back(r);
            minDeque.push_back(r);
            while (abs(nums[maxDeque.front()] - nums[minDeque.front()]) > limit) {
                l++;
                if (maxDeque.front() < l) maxDeque.pop_front();
                if (minDeque.front() < l) minDeque.pop_front();
            }            
            ans = max(ans, r - l + 1);
        }
        return ans;
    }
};
  • 时间复杂度:每个元素最多入队和出队常数次,复杂度为
  • 空间复杂度:
最后

巨划算的 LeetCode 会员优惠通道目前仍可用 ~

使用福利优惠通道 leetcode.cn/premium/?promoChannel=acoier,年度会员 有效期额外增加两个月,季度会员 有效期额外增加两周,更有超大额专属 🧧 和实物 🎁 福利每月发放。

我是宫水三叶,每天都会分享算法知识,并和大家聊聊近期的所见所闻

欢迎关注,明天见。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐