前端面试中常见的算法问题读后整理

看到有一篇写前端面试中常见的算法文章,里面的例子很简单,但也挺有趣。

重要的是,其实每个问题,都不止一个解答,我们可以从各个方面细想一下,拓展一下思路。

原文:前端面试中的常见的算法问题

判断一个字符串是否回文

利用js数组实现

js的数组是一个很强大的数据结构,我们可以活用其已实现的原生方法做很多事,比如,这个例子中,判断一个字符串是否是回文。

步骤:

将字符串拆分成数组

将字符串拆分成数组其实也也有多种方法:

split()方法

3letstr_to_array =function(str){

returnstr.split('');

}

Array.prototype.map()

3letstr_to_array =function(str){

returnArray.prototype.map.call(str,function(x){returnx});

}

数组反转reverse()

拼接成字符串join()

letcheckPalindrom =function(str){

returnstr_to_array(str).reverse().join('');

}

活用数组的reduceRight()方法

我们可以直接在字符串上调用数组的reduceRight()方法将字符串逆转

letrs =Array.prototype.reduceRight.apply('abc',[function(pre,current){

returnpre + current;

},'']);

letcheckPalindrom =function(str){

returnstr == rs(str);

}

使用栈数据结构

我们在学习栈这个数据结构的时候,老师讲的最生动的一个例子就是,判断回文有木有。

先将字符串中字符依次入栈,然后出栈组成新的字符串,即为逆转的字符串,然后做比较。

去掉一些整型数组中重复的值

直接使用es6的Set

3letunique =function(array){

return[...newSet(array)];

}

使用Object

我们知道Object对象的键是唯一的,可以利用这个特性为数组去重。

letunique =function(array){

letro = {};

letra = [];

array.forEach(item=>{

if(!ro[item]){

ro[item] = item;

ra.push(item);

}

});

returnra;

}

统计一个字符串出现最多的字母

首先我们要先统计字符串中各个字符出现的次数,我们可以使用最笨的遍历方法进行统计:

letcountChar =functioncountChar(str){

letro = {};

for(letcofstr){

if(!ro[c]){

ro[c] =1;

}else{

ro[c] ++;

}

}

returnro;

}

当然,也使用数组的reduce()方法进行统计,因为这个方法就适合进行统计计算。

letcountChar =functioncountChar(str){

returnArray.prototype.reduce.call(str,function(pre,current){

if(pre[current]){

pre[current] ++;

}else{

pre[current ] =1;

}

returnpre;

},{});

}

然后,从刚才统计出的数中查找出出现次数最多的字符

letfindMaxDuplicateChar =function(str){

letchars = countChar(str);

letmax =0;

letchar =null;

for(letcinchars){

if(chars[c] > max){

max = chars[c];

char = c;

}

}

returnchar;

}

不用临时变量,交换两个变量的值

原文中呢,作者教大家要合理运用+,-运算,最后给出如下答案:

functionswap(a , b){

b = b - a;

a = a + b;

b = a - b;

return[a,b];

}

module.exports = swap;

很巧妙,对吧,确实是合理运用了+,-运算,但是为什么呢?合理运用*,/运算呢?

a = a * b;

b = a / b;

a = a / b;

合理运用*,/好像也可以啊,对吧。

其实解决问题,我们应该从根上去解决,不能简单的说’合理运用’就敷衍过去了。

题目是,不用临时变量,临时变量是干嘛的呢?当然是存储临时值用的了,对吧。

那么,不用临时变量,我们可以把临时值存储到当前现有的变量中,对吧。

就好像是创造了一个临时变量一样。上面两个例子中,都是用两个变量的差或两个变量的积作为临时值,然后存储到其中一个变量,再由相应的运算交换两个变量的值。

明白了这个道理后,我们再合理一下嘛,对吧,利用两个变量的和作为临时值:

a = a + b;

b = a - b;

a = a - b;

注意:这里慎用两个变量的商作为临时值,因为如果两个变量除不尽,由于js中除法运算会舍掉余数,则会发生问题。

我们除了使用+,-,*,/四则运算创造‘临时变量’外,还可以使用位运算

a = a ^ b;

b = b ^ a;

a = a ^ b;

这个比上面的四则运算就要稍难理解了,这里运用了位运算中的异或运算。

对于异或运算的说明,还有不明白的可以回去翻翻大学的课本。

第一行 a = a ^ b;即创造了一个临时值存储在a中。

b = b ^ a

相当于

b = b ^ (a ^ b) = b ^ b ^ a = a

同理,

a = a ^ b

相当于

a = (a ^ b) ^ (b ^ (a ^ b)) = a^b^b^a^b = a^a^b^b^b = 0^0^b = b

找出数组中最大差值

可以直接遍历数组,找出最大值和最小值,然后做差。但是呢,那样就没意思了,对吧,我们可以直接使用数组的reduce()方法找出最大值和最小值。

letgetMaxProfit =functiongetMaxProfit(arr){

letmax_min = arr.reduce(function(pre,current){

if(pre.min > current){

pre.min = current;

}

if(pre.max < current){

pre.max = current;

}

returnpre;

},{min:arr[0],max:arr[0]});

returnmax_min.max - max_min.min;

}

当然,使用reduce()貌似还是有点麻烦啊,js的Math对象不是有max()和min()方法嘛,直接用这两个方法找出最大值和最小值就好了啊:

letgetMaxProfit =functiongetMaxProfit(arr){

letmax =Math.max.apply(Math,arr);

letmin =Math.min.apply(Math,arr);

returnmax - min;

}

这里使用了apply方法直接调用max()和min()来获取最大值和最小值。

我们都知道js中apply和call两个方法是功能相同的两个方法,只是传参方式不同。call方法传递参数列表,而apply传递参数对象或数组。

在es6中新添加了一个...操作符,用于将数组展开成列表,具体可参见MDN上的文档

因此,我们这里可以使用该操作符,直接调用max()和min()方法:

letgetMaxProfit =functiongetMaxProfit(arr){

letmax =Math.max(...arr);

letmin =Math.min(...arr);

returnmax - min;

}

位操作

20世纪70年代末到80年代末,Digital Equipment的VAX计算机是一种非常流行的机型。它没有布尔运算AND和OR指令,只有bis(位设置)和bic(位清除)这两个指令。两种指令的输入都是一个数据字x和一个掩码字m。他们生成一个结果z,z是由根据掩码m的位来修改x的位得到的。使用bis指令,就是在m为1的每个位置上,将z对应的位设置为1.使用bic指令,在m为1的每个位置,将z对应的位设置为0。

只使用bis和bic指令,完成按位|和^运算。

//bis和bic声明

intbis(intx,intm);

intbic(intx,intm);

//完成如下 | 运算 和 ^ 运算

intbool_or(intx,inty){

intresult = ______ ;

returnresult;

}

intbool_xor(intx,inty){

intresult = ______ ;

returnresult;

}

这其实是一道逻辑题目,由已知的bis运算逻辑和bic运算逻辑,用这两种运算去实现其他的运算。

bis运算就是在掩码位为1的位设置为1,其他位不变。而bic运算是在掩码位为1的位置设置为0,其他不变。

举个例子:

x  11010100

m  10100101

bis --------

11110101

x  11010100

m  10100101

bic --------

01010000

好了,那怎么利用这两种运算指令实现按位|和^运算呢?

仔细分析一下 bis 运算,所有掩码位为1的位,结果都是1,其他为0的位,还是按照原来的位,这不就是按位|运算么?

于是,第一个有了:

intbool_or(intx,inty){

intresult = bis(x,y) ;

returnresult;

}

那^运算呢?

我们都知道,异或运算运算法则为:a⊕b=(¬a∧b)∨(a∧¬b),a⊕b=(¬a∨b)∧(a∨¬b)。至于为什么,可以列真值表验证。

这里我们采用第一个运算法则:a⊕b=(¬a∧b)∨(a∧¬b)。

bic运算是怎么来的呢?bic(a,b)是将a上对应b为1的位变为0,其他不变。那么,不就是相当于先将b取反,然后和a进行按位与&运算么,就是:

bic(a,b) = a & (~b)

于是,再利用异或第一个运算法则:a⊕b=(¬a∧b)∨(a∧¬b)

我们可以得出:

intbool_xor(intx,inty){

intresult = bis(bic(x,y),bic(y,x));

returnresult;

}

js实现二叉搜索树

啥也不说了,直接看我github上的代码吧。

https://github.com/coolcao/dsa_js/blob/master/src/BSTree.js

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容