美团的破局之路(含笔试原题)

写在前面

中概惨,美团最近更是惨上加惨。

利润率个位数,财报爆雷,现在还被谣言击穿防线,造成单日 <math xmlns="http://www.w3.org/1998/Math/MathML"> 5 5 </math>5 个点以上的跌幅。

自从字节的现象级产品 抖音 做出流量后,往各个方向扩张的脚步就从未停下。

其中就包括对涵盖"线下消费"一条龙的 美团 的围剿。

最近网传: 抖音要收购阿里的饿了么

该消息现在已被抖音官方辟谣,但这个消息能够流传开来,是有它的逻辑的。

除了是 字节跳动一贯的围剿风格

另一方面,是 阿里巴巴目前在收缩战线,最近不断出售前期投资项目的股期股权

因此,对于出售饿了么,资本持基本相信态度。

对于美团,目前没有太好的破局思路。

国内几乎所有互联网,流量虽大,但几乎没有什么核心护城河。

美团能做的东西,抖音也能做,但光靠那 20%-30% 的用户体验差别,是不足以让这"第一名"的头衔易主的。

消费者/用户的心智空间,通常只会记住第一名,只要不发生实际上的区别,第一名会永远的赢下去。

美团目前能做的,就是熬到字节跳动没有耐心,最终放弃围剿。

毕竟字节跳动的围剿也是有成本次数限制的。

无论是"对教培的围剿"(政策)、"对游戏的围剿"、或是"对 SHEIN 的围剿"目前都几乎接近尾声。

美团只能把希望放在,抖音会放弃对「线下业务」的围剿。

这是一个合理的期望,毕竟抖音的流量有更好的变现方式,单纯为了搞垮美团而无底线的违背经济原则是不可持续的。

剩者为王,美团只能重新和抖音,再走一次当时和点评走过的路。

闲话聊完了,回归主线,咱可是算法区博主,来一道美团笔试面试真题。

题目描述

平台:LeetCode

题号:93

有效 IP 地址正好由四个整数(每个整数位于 0255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。

例如:"0.1.2.201""192.168.1.1" 是有效 IP 地址,

但是 "0.011.255.245""192.168.1.312""192.168@1.1" 是无效 IP 地址。

给定一个只包含数字的字符串 s ,用以表示一个 IP 地址。返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。

不能重新排序或删除 s 中的任何数字,可以按任何顺序返回答案。

示例 1:

ini 复制代码
输入:s = "25525511135"

输出:["255.255.11.135","255.255.111.35"]

示例 2:

ini 复制代码
输入:s = "0000"

输出:["0.0.0.0"]

提示:

  • <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 < = s . l e n g t h < = 20 1 <= s.length <= 20 </math>1<=s.length<=20
  • s 仅由数字组成

回溯算法

一道求所有方案的题目,只能是没有太多优化的「爆搜」做法。

设计递归函数 void dfs(int idx, int n, List<Integer> cur),其中 idx 代表当前处理字符串 s 的哪个位置,n 代表字符串 s 总长度,而 cur 的则是代表子串 <math xmlns="http://www.w3.org/1998/Math/MathML"> s [ 0... ( i d x − 1 ) ] s[0 ... (idx - 1)] </math>s[0...(idx−1)] 部分的具体划分方案。

用题目样例 s = "25525511135" 作为 🌰,n 固定为 11

idx = 3 时,cur 为 <math xmlns="http://www.w3.org/1998/Math/MathML"> s [ 0...2 ] = 255 s[0...2] = 255 </math>s[0...2]=255,cur 部分的划分方案可能是 [2,5,5][2,55][25,5][255] 之一。

cur 的基础上,我们继续爆搜剩余部分,即递归执行 dfs(idx, n, cur),算法会将剩余部分的划分方案添加到 cur 上,我们只需要确保每次追加到 cur 的数值符合要求即可(没有前导零 且 范围在 <math xmlns="http://www.w3.org/1998/Math/MathML"> [ 0 , 255 ] [0, 255] </math>[0,255] 中)。

在单次回溯过程中,我们可以将 idx 作为当前划分数字的左端点,通过枚举的形式找到右端点 j,并将当前数字 <math xmlns="http://www.w3.org/1998/Math/MathML"> s [ i d x . . . ( j − 1 ) ] s[idx ... (j - 1)] </math>s[idx...(j−1)] 加到 cur 中(若合法),回溯到底后再添加到 cur 的元素进行移除。

idx = n 代表整个 s 已经处理完成,若此时 cur 恰好有 <math xmlns="http://www.w3.org/1998/Math/MathML"> 4 4 </math>4 个元素,说明我们找到了一组合法方案,将其拼接成字符串追加到答案数组中。

同时也是由于划分过程中 cur 最多只有 <math xmlns="http://www.w3.org/1998/Math/MathML"> 4 4 </math>4 个元素,我们可以用此做简单剪枝。

Java 代码:

Java 复制代码
class Solution {
    List<String> ans = new ArrayList<>();
    char[] cs;
    public List<String> restoreIpAddresses(String s) {
        cs = s.toCharArray();
        dfs(0, cs.length, new ArrayList<>());
        return ans;
    }
    void dfs(int idx, int n, List<Integer> cur) {
        if (cur.size() > 4) return ;
        if (idx == n) {
            if (cur.size() == 4) {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < 4; i++) sb.append(cur.get(i)).append(".");
                ans.add(sb.substring(0, sb.length() - 1));
            }
        } else {
            for (int i = idx; i < n; i++) {
                int t = 0;
                for (int j = idx; j <= i; j++) t = t * 10 + (cs[j] - '0');
                if (cs[idx] == '0' && i != idx) break;
                if (t > 255) break;
                cur.add(t);
                dfs(i + 1, n, cur);
                cur.remove(cur.size() - 1);
            }
        }
    }
}

C++ 代码:

C++ 复制代码
class Solution {
public:
    vector<string> ans;
    string s;
    void dfs(int idx, int n, vector<int>& cur) {
        if (cur.size() > 4) return ;
        if (idx == n) {
            if (cur.size() == 4) {
                string sb;
                for (int i = 0; i < 4; i++) sb += to_string(cur[i]) + ".";
                ans.push_back(sb.substr(0, sb.length() - 1));
            }
        } else {
            for (int i = idx; i < n; i++) {
                int t = 0;
                for (int j = idx; j <= i; j++) t = t * 10 + (s[j] - '0');
                if (s[idx] == '0' && i != idx) break;
                if (t > 255) break;
                cur.push_back(t);
                dfs(i + 1, n, cur);
                cur.pop_back();
            }
        }
    }
    vector<string> restoreIpAddresses(string _s) {
        s = _s;
        vector<int> cur;
        dfs(0, s.length(), cur);
        return ans;
    }
};

Python 代码:

Python 复制代码
class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        ans = []
        def dfs(idx, n, cur):
            if len(cur) > 4:
                return 
            if idx == n:
                if len(cur) == 4:
                    ans.append('.'.join(cur))
            else:
                for i in range(idx, n):
                    t = 0
                    for j in range(idx, i + 1):
                        t = t * 10 + (ord(s[j]) - ord('0'))
                    if s[idx] == '0' and i != idx:
                        break
                    if t > 255:
                        break
                    cur.append(str(t))
                    dfs(i + 1, n, cur)
                    cur.pop()
        dfs(0, len(s), [])
        return ans

TypeScript 代码:

TypeScript 复制代码
function restoreIpAddresses(s: string): string[] {
    const ans = new Array<string>()
    function dfs(idx: number, n: number, cur: Array<number>): void {
        if (cur.length > 4) return 
        if (idx == n) {
            if (cur.length == 4) {
                let str = ''
                for (let i = 0; i < 4; i++) str += cur[i] + "."
                ans.push(str.substring(0, str.length - 1))
            }
        } else {
            for (let i = idx; i < n; i++) {
                let t = 0
                for (let j = idx; j <= i; j++) t = t * 10 + (s.charCodeAt(j) - '0'.charCodeAt(0))
                if (s[idx] == '0' && i != idx) break
                if (t > 255) break
                cur.push(t)
                dfs(i + 1, n, cur)
                cur.pop()
            }
        }
    }
    dfs(0, s.length, new Array<number>())
    return ans
}
  • 时间复杂度:爆搜不讨论时空复杂度
  • 空间复杂度:爆搜不讨论时空复杂度

更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地 🎉🎉

相关推荐
想用offer打牌2 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
崔庆才丨静觅2 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
KYGALYX3 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅3 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
爬山算法4 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端