前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >特斯拉一面,竟是最简单的算法题

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

作者头像
宫水三叶的刷题日记
发布2023-12-13 09:28:30
3220
发布2023-12-13 09:28:30
举报

写在前面

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

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

题目描述

平台:LeetCode

题号:3

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

示例 1:

代码语言:javascript
复制
输入: s = "abcabcbb"

输出: 3 

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

示例 2:

代码语言:javascript
复制
输入: s = "bbbbb"

输出: 1

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

示例 3:

代码语言:javascript
复制
输入: s = "pwwkew"

输出: 3

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

示例 4:

代码语言:javascript
复制
输入: s = ""

输出: 0

提示:

0 <= s.length <= 5 \times 10^4
  • 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 代码:

代码语言:javascript
复制
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 代码:

代码语言:javascript
复制
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++ 代码:

代码语言:javascript
复制
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 代码:

代码语言:javascript
复制
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;
};
  • 时间复杂度:虽然有两层循环,但每个字符在哈希表中最多只会被插入和删除一次,复杂度为
O(n)
  • 空间复杂度:使用了哈希表进行字符记录,复杂度为
O(n)

总结

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

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

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

说明在那个算法笔面刚出现,甚至是 LeetCode 刚建站,总共只有 150 道题目的那个年代,像「滑动窗口」这样的知识点,还不被大家所掌握,绝大多数只能给出双层循环的

O(n^2)

解法。

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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 宫水三叶的刷题日记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面
  • 题目描述
  • 滑动窗口
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档