面经中的算法题总结

1、交换两数组元素使和的差最小

题目:有两个序列a,b,大小都为n,序列元素的值任意整数,无序;
要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。
例如: var a = [100,99,98,1,2, 3],b = [1, 2, 3, 4,5,40];

思路:
当前数组a和数组b的和之差为: A = sum(a) - sum(b),a的第i个元素和b的第j个元素交换后,a和b的和之差为
A’ = sum(a) - a[i] + b[j] - (sum(b) - b[j] + a[i])
= sum(a) - sum(b) - 2 (a[i] - b[j])
= A - 2 (a[i] - b[j])
设x = a[i] - b[j],则|A| - |A’| = |A| - |A-2x|。假设A > 0,当x 在 (0,A)之间时,做这样的交换才能使得交换后的a和b的和之差变小,x越接近A/2效果越好,如果找不到在(0,A)之间的x,则当前的a和b就是答案。
参考链接

2、最长子序列问题

一般都是采用两层动态规划解决
参考链接

3、不用第三变量交换两个数

加减法或是异或法。

4、100层两个玻璃球问题。

参考链接

5、字符串循环移位:三次翻转

参考链接

6、实现memcpy,考虑内存重叠

参考链接

7、给两个文件,分别有100亿个URL,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法。

  • 1G内存为10亿字节,所以无法把100亿直接载入内存,可以先通过hash将两个大文件分成多个小文件,所有可能相同的URL都在相同的小文件中。再采用hash_set对每一对小文件进行处理。
  • 近似算法采用BloomFilter

8、一个数组一个数字出现奇数次,其余数字出现偶数次,求这个数字

异或。

9、C++定义不能被继承的类

主要是通过友元加构造函数私有实现。
参考

10、两个无序数组找中位数

以两个数组的平均大小建立最大堆即可。
参考

11、手撕堆排序

参考

12、不使用乘号运算符实现两个数相乘

位运算即可,a可以遍历b中为1的位,左移该位的高度,累加即可。
参考

13、最长重复子串

给出一个字符串S,返回其最长重复子串。
保存s字符串的所有后缀,对所有后缀进行排序(自然排序),比较排序后的相邻的后缀的最长公共子串(两个后缀从第一个字符开始的就相等得到公共子串),求出最长的公共子串。
参考

14、64匹马,8个赛道,找出跑得最快的4匹马

参考

15、c实现c++的继承和多态

继承主要通过子结构体中定义一个父结构体成员,该成员要放在第一位,为后续强制转换。
c中结构体不能有成员函数,函数主要通过函数指针实现。
多态:让父类指针指向子类的对象,由于类型不匹配所以要进行强转。
参考

16、老鼠毒药问题

1000瓶无色无味的药水,其中有一瓶毒药,10只小白鼠拿过来做实验。喝了无毒的药水第二天没事儿,喝了有毒的药水后第二天会死亡。如何在一天之内(第二天)找出这瓶有毒的药水?
思路就是用二进制,2^10=1024,也就是10只小白鼠最多能验出1024瓶药水,哪个有毒。小白鼠编号,1-10。瓶子也编号,1-1000,然后把瓶子的编号转变为二进制数。如果第几位是1,就把这瓶水给第几个小白鼠喝。最后大概每个小白鼠喝500瓶药水的混合液。如果还不懂,下面列几个数字解释一下。
瓶子编号 二进制数 第几个小白鼠喝1 0000000001 12 0000000010 23 0000000011 1,24 0000000100 35 0000000101 1,3大概就是这意思,再反过来,假如1号和3号小白鼠死了,死的小白鼠用1表示,再写成2进制数:0000000101,转化为十进制数是5,从上面列出来的也可以看出1,3都喝了5号瓶的水,所以就是第五瓶水有毒。
解决方案
1)我们将1000瓶液体编号1~1000,然后将编号转化为10位二进制,如1号就是0000000001;
2)将十只小白鼠编号1~10;
3)将液体的二进制编号上为1的位数给对应的小白鼠喝,如液体编号为 1111100000,那就是1 - 5号小白鼠不喝这瓶液体,6~10号小白鼠喝这瓶液体;
4)一星期后观察小白鼠的死亡情况,如果1 - 5号小白鼠死亡,6 - 10号小白鼠存活,那么有毒的那瓶液体对应的二进制编码为 0000011111;
5)将第四步得到的二进制编码转化为十进制,这里是31号,因此我们可以推断出编号为31的液体是被污染的。

17、最长全一串

给你一个01字符串,定义答案=该串中最长的连续1的长度,现在你有至多K次机会,每次机会可以将串中的某个0改成1,现在问最大的可能答案。
双指针法,窗口内把k都用完,参考。

18、种花(岛屿沉没)

公园里有N个花园,初始时每个花园里都没有种花,园丁将花园从1到N编号并计划在编号为i的花园里恰好种A_i朵花,他每天会选择一个区间[L,R](1≤L≤R≤N)并在编号为L到R的花园里各种一朵花,那么园丁至少要花多少天才能完成计划?
贪心算法即可,参考

19、路由器问题

一条直线上等距离放置了n台路由器。路由器自左向右从1到n编号。第i台路由器到第j台路由器的距离为| i-j |。 每台路由器都有自己的信号强度,第i台路由器的信号强度为ai。所有与第i台路由器距离不超过ai的路由器可以收到第i台路由器的信号(注意,每台路由器都能收到自己的信号)。问一共有多少台路由器可以收到至少k台不同路由器的信号。
维护每个路由器能到达的左右边界,然后从左往右遍历这个左右边界数组,维护一个数组dp,某个位置碰到左边界加一,右边界减一。最后从左往右遍历dp,维护一个tmp加dp的值。当tmp大于k的位置即为所求。参考

20、一个硬币,抛正面的概率p,反面的概率1-p,构造一个1/2的事件

抛两次,一正一反和一反一正的概率是相同的。

21、求比n小的一个数,使其各位数的乘积最大

贪心,保证尽可能多的9。

22、最大正方形:子矩阵问题

n*m的棋盘,每个格子有一个0/1的数值;求一个最大的正方形子矩阵,要求矩阵内都是1。dp即可解决,参考

23、一段公路上1小时内有汽车经过的概率为96%,求30分钟内有汽车经过的概率

1个小时内有车通过的概率是0.96,那么个一个小时内没有车通过的概率是0.04。我们可以把单位分解为30分钟:就相当于在连续的两个30分钟里面都没有出现任何车辆即x² = 0.04 解得 x=0.2那么半小时内出现车辆的概率就是0.8.

24、搜索旋转数组

搜索旋转数组。给定一个排序后的数组,包含n个整数,但这个数组已被旋转过很多次了,次数不详。请编写代码找出数组中的某个元素,假设数组元素原先是按升序排列的。若有多个相同元素,返回索引值最小的一个。
在这里插入图片描述

核心:通过target、mid和left判断是在哪个区域。确定区域之后二分法即可。

25、欧拉筛找素数

主要用线性筛即可
参考

26、位运算

x & (-x):获取二进制中最右边的1
x & (x - 1):去除二进制中最右边的1

27、瓶子换饮料问题

1000瓶饮料,3个空瓶子能够换1瓶饮料,问最多能喝几瓶?
拿走3瓶,换回1瓶,相当于减少2瓶。但是最后剩下4瓶的时候例外,这时只能换1瓶。所以我们计算1000减2能减多少次,直到剩下4.(1000-4=996,996/2=498)所以1000减2能减498次直到剩下4瓶,最后剩下的4瓶还可以换一瓶,所以总共是1000+498+1=1499瓶。

28、24小时里面时针分针秒针可以重合几次

时分秒重合:2次
时分重合:22次
这类问题实际上是分针追时针的追击问题,它的公式是:
t= s/(v1-v2) ,S=60(格)
分针速度:V1=1 格/分
时针速度:V2= 1/12 格/分
所以,计算得到t=65+5/11 分
根据以上计算,每隔65+5/11 分时针和分针重合一次。 即,从12点开始,每经过65+5/11 分,时针与分针重合一次, 全天共重合24*60/(65+5/11) = 22次

29、实现sqrt

牛顿迭代法快速寻找平方根”,具体步骤如下:
求出根号a的近似值:首先随便猜一个近似值x,然后不断令x等于x和a/x的平均数,迭代个六七次后x的值就已经相当精确了。
例如,我想求根号2等于多少。假如我猜测的结果为4,虽然错的离谱,但你可以看到使用牛顿迭代法后这个值很快就趋近于根号2了:
( 4 + 2/4 ) / 2 = 2.25
( 2.25 + 2/2.25 ) / 2 = 1.56944…
( 1.56944…+ 2/1.56944…) / 2 = 1.42189…
( 1.42189…+ 2/1.42189…) / 2 = 1.41423…
这种算法的原理很简单,我们仅仅是不断用(x,f(x))的切线来逼近方程x ^ 2-a=0的根。根号a实际上就是x ^ 2-a=0的一个正实根,这个函数的导数是2x。也就是说,函数上任一点(x,f(x))处的切线斜率是2x。那么,x-f(x)/(2x)就是一个比x更接近的近似值。代入 f(x)=x ^ 2-a得到x-(x^2-a)/(2x),也就是(x+a/x)/2。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值