

老哥来看看跳槽常考算法呗 [第 1 期] 前端算法精选-字符串系列
source link: https://v2ex.com/t/648140
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

很多前端工程师甚至很多研发工程师都缺乏数据结构和算知识,前端算法精选系列是一个针对常见的、高频的算法题做的一个算法解析系列,文章会给出详细的思路和解答,希望可以帮助到你。
无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3
输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
先看一下这道题的要求,它要求返回一个字符串中无重复字符的最大子串长度,时间复杂度和空间复杂度要求尽可能的低,有以下的思路
既然是最大子串的长度,首先最明显的思路就是维护一个最大不重复子串的变量和最大长度的变量。比如对于 “abcabcbb” 来说,维护一个 cur 来存当前最大不重复子串、max 维护最大长度,那么就有以下过程:
-
遍历到 a,此时 cur='',不包含'a',所以 cur=cur+'a'='a'; cur 长度为 1 大于 max 的初始值 0,所以更新 max=1 ;
-
遍历到 b,此时 cur='a',不包含'b',所以 cur=cur+'b'='ab'; cur 长度为 2 大于 max,所以更新 max=2 ;
-
遍历到 c,此时 cur='ab',不包含'c',所以 cur=cur+'c'='abc',cur 长度为 3 大于 max,所以更新 max=3 ;
-
遍历到 a,此时 cur='abc',包含'a',所以截掉'a'以及它之前的字符串得到 cur='bc',然后再加上这一轮的'a',得到 cur='bca'; cur 长度为 3 不大于 max,所以不更新 max
-
按照以上的逻辑继续遍历...
代码如下:
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
if(s.length === 0 || s.length === 1)
return s.length;
let cur = '', max = '';
for(let i = 0;i < s.length;i++) {
const index = cur.indexOf(s[i]);
if(index >= 0) {
cur = cur.slice(index+1);
}
cur += s[i];
if(cur.length >= max.length)
max = cur;
}
return max.length;
};
最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀,如果不存在公共前缀,返回空字符串。
输入: ["flower","flow","flight"] 输出: "fl"
输入: ["dog","racecar","car"] 输出: "" 解释: 输入不存在公共前缀。
这道题求一组字符串的最长公共前缀,思路可以转化成先以第一个字符串为最长公共前缀,然后跟第 2 个字符串对比,截取公共前缀部分,再跟第 3 个字符串对比,截取公共部分...依次进行下去,如果途中遇到公共前缀部分为空,则说明不存在公共前缀,函数返回空字符串。代码如下:
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
if(strs.length === 0)
return "";
let prefix = strs[0];
for(let i = 1;i < strs.length;i++) {
let cur = strs[i];
let index = 0;
if(prefix === '')
break;
while(index < prefix.length && index < cur.length) {
if(prefix[index] !== cur[index])
break;
index++;
}
prefix = prefix.slice(0, index);
console.log(prefix);
}
return prefix;
};
欢迎关注前端亚古兽微信公众号,持续干货输出
第 1 条附言 · 2020-02-28 10:13:38 +08:00
第 2 条附言 · 2020-02-28 13:39:51 +08:00
发现之前的解法时间复杂度比较高,在最坏的情况下复杂度是O(n^2);所以优化一下,用空间换时间,维护一个map存储当前字符串每个字符出现的次数;时间复杂度O(n),空间复杂度O(n) 之前写的比较急,感谢老哥指出问题
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
if(s.length === 0 || s.length === 1)
return s.length;
let cur = '', max = 0, map = {};
for(let left = 0, right = 0;right < s.length;right++) {
const rightChar = s[right];
if(map[rightChar]) {
map[rightChar]++;
} else {
map[rightChar] = 1;
}
// 如果发现重复的字符,会从左侧一直删除,直到重复的字符已经被删除为止
while(map[rightChar] > 1) {
const leftChar = s[left];
map[leftChar]--;
left++;
}
if(right - left + 1 > max) {
max = right - left + 1;
}
}
return max;
};
Recommend
-
55
硬件 - @lostInnight -
-
13
面试常考,64个数据分析常用术语 !
-
13
讲两道常考的阶乘算法题 👆让天下没有难刷的算法!若 GitBook 访问太慢,可尝试
-
27
V2EX › 程序员 迫于小组内唯一会前端的老哥跑路,求前端老哥们给个 VUE 相关的前端速成路线
-
11
大厂常考的Spring面试题准备了一个月的八股文,经历了二十几场面试之后,发现Spring很受面试官青睐。最近有空将Spring常见的面试题总结了一下,希望对大家有所帮助。文章目...
-
7
教资面试结构化常考题型:综合分析类书...
-
8
1、路由的起源路由其实就是url和文件的映射,在后端控制路由在接收到客户端发来的http请求时,会根据响应的url来找到相应的映射函数,执行得到返回值给客户端。对于简单的静态...
-
7
1.路由的起源路由其实就是url和文件的映射,在后端控制路由在接收到客户端发来的http请求时,会根据响应的url来找到相应的映射函数,执行得到返回值给客户端。对于简单的静态资源服务,所有url的映射函数是一个文件读取操作;对于动...
-
9
V2EX › 问与答 各位前端老哥来看看这种照片墙怎么实现最好?
-
9
V2EX › 问与答 有没有比较懂 PC 的老哥进来帮忙看看问题..电脑黑屏重启
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK