特斯拉一面,竟是简单算法题

写在前面

这道题不要说是特斯拉,可能放眼所有存在"算法笔面"环节的互联网公司,也是标准 Easy 水平。

以至于遇到该题目的同学都有"准备过于充分"的感觉: 🤣

题目描述

平台:LeetCode

题号:3

给定一个字符串,请你找出其中不含有重复字符的「最长子串」的长度。

示例 1:

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

输出: 3 

解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

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

输出: 1

解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

makefile 复制代码
输入: s = "pwwkew"

输出: 3

解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

示例 4:

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

输出: 0

提示:

  • <math xmlns="http://www.w3.org/1998/Math/MathML"> 0 < = s . l e n g t h < = 5 × 1 0 4 0 <= s.length <= 5 \times 10^4 </math>0<=s.length<=5×104
  • s 由英文字母、数字、符号和空格组成

滑动窗口

定义两个指针 startend[start:end] 表示当前处理到的子串。

子串 [start:end] 始终满足要求:无重复字符。

从前往后进行扫描 s,用哈希表记录 [start:end] 中每字符的出现次数。

遍历过程中,end 不断自增,将第 end 个字符在哈希表中出现的次数加一。

right 为下标 end 对应的字符,当满足 map.get(right) > 1 时,代表此前出现过第 end 位对应的字符。

此时更新 start 的位置(使其右移),直到不满足 map.get(right) > 1 (代表 [start:end] 恢复满足无重复字符的条件),再用 [start:end] 长度更新答案。

Java 代码:

Java 复制代码
class Solution {
    public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>();
        int ans = 0;
        for (int start = 0, end = 0; end < s.length(); end++) {
            char right = s.charAt(end);
            map.put(right, map.getOrDefault(right, 0) + 1);
            while (map.get(right) > 1) {
                char left = s.charAt(start);
                map.put(left, map.get(left) - 1);
                start++;
            }
            ans = Math.max(ans, end - start + 1);
        }
        return ans;
    }
}

Python 代码:

Python 复制代码
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        map = {}
        ans = 0
        start = 0
        for end in range(len(s)):
            right = s[end]
            map[right] = map.get(right, 0) + 1
            while map[right] > 1:
                left = s[start]
                map[left] = map[left] - 1
                start += 1
            ans = max(ans, end - start + 1)
        return ans

C++ 代码:

C++ 复制代码
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char, int> map;
        int ans = 0;
        for (int start = 0, end = 0; end < s.length(); end++) {
            char right = s[end];
            map[right] = map[right] + 1;
            while (map[right] > 1) {
                char left = s[start];
                map[left] = map[left] - 1;
                start++;
            }
            ans = max(ans, end - start + 1);
        }
        return ans;
    }
};

TypeScript 代码:

TypeScript 复制代码
function lengthOfLongestSubstring(s: string): number {
  const map: { [key: string]: number } = {};
  let ans = 0;
  let start = 0;
  for (let end = 0; end < s.length; end++) {
      const right = s.charAt(end);
      map[right] = (map[right] || 0) + 1;
      while (map[right] > 1) {
          const left = s.charAt(start);
          map[left] = (map[left] || 0) - 1;
          start++;
      }
      ans = Math.max(ans, end - start + 1);
  }
  return ans;
};
  • 时间复杂度:虽然有两层循环,但每个字符在哈希表中最多只会被插入和删除一次,复杂度为 <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n ) O(n) </math>O(n)
  • 空间复杂度:使用了哈希表进行字符记录,复杂度为 <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n ) O(n) </math>O(n)

总结

现在看来这道题确实简单到离谱。

但在 LeetCode 平台中,这道题的难度标签却是「中等」。

其实从 3 这样较小的题号就能发现,这是属于最早期的那批题目。

说明在那个算法笔面刚出现,甚至是 LeetCode 刚建站,总共只有 150 道题目的那个年代,像「滑动窗口」这样的知识点,还不被大家所掌握,绝大多数只能给出双层循环的 <math xmlns="http://www.w3.org/1998/Math/MathML"> O ( n 2 ) O(n^2) </math>O(n2) 解法。

反观现在的笔试面试,一些在招聘市场"供过于求"的公司,有时候还会把网络流搬上桌面 ...

可见,算法内卷的道路只会放缓,不会停止,没有尽头。

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

相关推荐
@大迁世界20 分钟前
AR 如何改变我们构建网站的方式
后端·ar·restful
RainbowSea21 分钟前
NVM 切换 Node 版本工具的超详细安装说明
java·前端
读书点滴26 分钟前
笨方法学python -练习14
java·前端·python
RainbowSea27 分钟前
问题:后端由于字符内容过长,前端展示精度丢失修复
java·spring boot·后端
Mintopia33 分钟前
四叉树:二维空间的 “智能分区管理员”
前端·javascript·计算机图形学
Mintopia44 分钟前
Three.js 深度冲突:当像素在 Z 轴上玩起 "挤地铁" 游戏
前端·javascript·three.js
风象南44 分钟前
SpringBoot 控制器的动态注册与卸载
java·spring boot·后端
Penk是个码农1 小时前
web前端面试-- MVC、MVP、MVVM 架构模式对比
前端·面试·mvc
MrSkye1 小时前
🔥JavaScript 入门必知:代码如何运行、变量提升与 let/const🔥
前端·javascript·面试
白瓷梅子汤1 小时前
跟着官方示例学习 @tanStack-form --- Linked Fields
前端·react.js