你听说过摩尔投票法吗,web前端面试必问的问题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
img

正文

  1. 但如果光靠剩下的人判断领袖是存在漏洞的,例如 [1,2,2,1,3,3] 这种,前面两个候选人选票互相内耗了,第三个候选人也没有达到总票数的一般,因此还需要计数阶段,统计一下最后所剩候选人的票数是否达到总票数的一半。

图文讲解

看完阿包举的例子如果还不懂,咱们再来看个图文的。

思路

根据上面的算法思想,我们将当前票数最多的候选人与获得的票数(抵消后)分别存储在 majorcount 中。

当我们遍历下一个选票时,判断当前 count 是否为零:

  • 如果 count == 0 : 代表 major 空缺,直接将当前候选人赋值给 major,并将 count ++

  • count != 0 : 代表当前 major 的票数未被完全抵消,令 count --,不同意见的斯巴达勇士去激情对撞。

初始值 count = 0, major = -1

详细图解

[2,2,1,3,1,2,2] 为例。

遍历数组第一个元素 2,因 count == 0,所以将 2 赋值给 major,且票数 count = 1

在这里插入图片描述

第二个数组元素依旧是候选人 2,得票数 count ++

在这里插入图片描述

第三个元素是 1,与 major 冲突,因此发生激情对撞,当前 major 的票数抵消 1 票。

在这里插入图片描述

第四个元素是 3, 与 major 冲突,产生激情对撞,当前 major 的票数抵消一票。

在这里插入图片描述

当遍历到第五个元素 1 时,此时 count = 0,说明 marjor 位置空缺,所以令 majro = 1,且 count = 1

在这里插入图片描述

第六个元素是 2,与 major 冲突,产生激情对撞,当前 major 的票数抵消 1 票,此时 count 又变为 0

在这里插入图片描述

遍历最后一个元素 2,当前 count = 0,说明 marjor 位置空缺,所以令 majro = 1,且 count = 1

在这里插入图片描述

遍历完毕,2 元素很有可能就是斯巴达新的领袖。

计数阶段: 统计 2 元素出现的次数是否大于一半,2 出现四次,大于一半,所以我宣布斯巴达共和国未来的领袖就是 2 了(怎么听起来怪怪的。。。)

真题实战


真题一:主要元素

题目来源: 面试题 17.10. 主要元素

题目描述:数组中占比超过一半的元素称之为主要元素。给你一个 整数 数组,找出其中的主要元素。若没有,返回 -1 。请设计时间复杂度为 O(N) 、空间复杂度为 O(1) 的解决方案

如果没有最后一句要求,肯定咱们大脑中第一瞬间想到的就是哈希表,使用哈希表存储每个元素的出现次数。

但是咱们现在可不是凡人啊,连斯巴达共和国的领袖都可以选举出来了,肯定要上摩尔选举法啊。

这个题的思想与我举得图文讲解极度类似,我就不多做赘述了。

/**

  • @param {number[]} nums

  • @return {number}

*/

var majorityElement = function(nums) {

let major = -1;

let count = 0;

for (var i = 0; i<nums.length; i++) {

if (count === 0) {

major = nums[i];

}

if (nums[i] === major) {

count++;

} else {

// 票数抵消

count–;

}

}

count = 0;

const length = nums.length;

// 计数阶段

for (var i = 0; i<nums.length; i++) {

if (nums[i] === major) {

count++;

}

}

return count * 2 > length ? major : -1;

};

真题二:求众数 II

题目来源: 229. 求众数 II

题目描述:给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。请设计时间复杂度为 O(N) 、空间复杂度为 O(1) 的解决方案

我当时刷这道题时苦思冥想,咋都想不出空间复杂度为 O(1)的解决方案,看官方题解醍醐灌顶,这也能摩尔投票法。咱们来一起分析一下:

做这个题之前,首先要理解:出现超过 ⌊ n/3 ⌋ 次的元素最多有 2 个。咱们可以稍微反证一下:如果出现了 2 个以上超过 ⌊ n/3 ⌋ 次的元素,例如 3 个,哪意味着当前数组中会存在 3 * ⌊ n/3 ⌋ > n,与现实冲突。

思路

我把这个题形象一下,其实就相当于斯巴达勇士们要选正副领袖,所以现在两个不同意见得勇士打架就不合理了,因为这两个勇士的候选人可能是正副领袖。

既然是要选两个领袖,那是不是也可以类比为三个不同意见得勇士打架抵消那,下面我们来具体操作一下,看看能不能实现:

如果数组中只有一个元素 x 超过了 ⌊ n/3 ⌋,把数组分为两部分:一部分为 kx,另一部分为 (n-k)/3 组三个不同的元素,如果三个不同元素会被抵消,最终只会剩下 kx

如果数组中有两个元素 x,y 超过了 ⌊ n/3 ⌋,把数组分为三部分:第一部分为 kx,第二部分为 ly,第三部分为 (n-k-l) / 3 组三个不同的元素,如果三个不同元素会被抵消,最终会剩下 kxly

通过上面得分析,三个不同意见的勇士相抵消是可以实现的,算法流程为:

  • 检查当前元素是否为第一个选中的元素或第二个选中的元素。如果存在相同,对应元素得票数加一。

  • 如果与两个元素都不相同,则三个不同得元素抵消一次

  • 抵消结束后,若存在最终选票大于 0 得元素,进行计数阶段,检查该元素次数是否大于 ⌊ n/3 ⌋

上代码:

/**

  • @param {number[]} nums

前端框架

前端框架太多了,真的学不动了,别慌,其实对于前端的三大马车,Angular、React、Vue 只要把其中一种框架学明白,底层原理实现,其他两个学起来不会很吃力,这也取决于你以后就职的公司要求你会哪一个框架了,当然,会的越多越好,但是往往每个人的时间是有限的,对于自学的学生,或者即将面试找工作的人,当然要选择一门框架深挖原理。

以 Vue 为例,我整理了如下的面试题。

Vue部分截图

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
rt/c6738a80c94640db83f7ffbf487ac5f0.png)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-54cmIhrs-1713230837201)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值