算法记录_2

这一章是关于第4章 数组

1. 如何找出数组中唯一的重复元素

第一种方法:空间换时间。建立一个hash表,在python中可以用字典来代替。思路:首先定义一个字典,将字典中的元素值(key值)都设置为0,将原数组中的元素一一映射到字典的key中,当对应key中的value为0时,置key的值为1,如果为1,表明是重复的。输出即可

第二种方法:累加求和。(如果数据量巨大时可能会溢出)

第三种方法:异或法。重要知识点,相同元素异或时,其运算结果是0;当不同的元素异或时,其运算结果不为0;任何数与数字0异或时,其运算结果为该数。在本题中可以将数组中的元素逐一进行异或运算,得到的值再与数字1,2,3...N进行异或运算。得到的结果就是重读的数

2.如何查找数组中元素的最大值和最小值

第一种方法:蛮力法。定义min和max两个变量,都初始化定义为数组首元素的值,然后从数组的第二个元素开始遍历,如果比max大,替换max,比min小,替换min。一共比较了2n-2次。

第二种方法:分治法。分治法就是将一个规模为n的,难以解决的大问题,分割成k个规模较小的子问题,采用各个击破、分而治之的策略得到各个子问题的解,然后将各个子问题的解进行合并,从而得到原问题解的一种方法。在本题中,将所有的元素两两分组,值小的数字放在左边,值大的数字放在右边,需要n/2次,这样最小的值一定都在左边,而最大的值一定都在右边,再从最左边、最右边找值即可,一共需要n/2*3次。

第三种方法:变形的分治法--递归法。将数组分成左右两个部分,在左边部分找最大最小值,再在右边部分找最大最小值,综合起来的最大最小值就是最后的结果,对于最左最右的划分可以用到递归的方法,直到最左最右只有两个值为止。

3.如何找出旋转数组的最小值 (有序数数组最开始的若干元素搬到数组的末尾,[3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该旋转最小的数字为1)

查找的话,我觉得大部分可以用二分法。给定两个指针 low(指向首端),high(指向尾端),正常情况(arr[high] 大于 arr[low], 如果没有代表数组没有旋转)。mid = (high + low )/ 2。下面分情况讨论 :

a. arr[mid] < arr[mid-1]; arr[mid] 就是最小值                               b.  arr[mid+1]<arr[mid]; arr[mid+1]就是最小值

c. arr[high] > arr[mid]; 在左边                            d  arr[high] < arr[mid]; 在右边

e.如果arr[high] = arr[mid] 并且 arr[low] = arr[mid],类似[2,2,2,1,2]等,只能左右遍历。

5. 如何找出数组中出现奇数次的数

第一种方法:字典法。将数组元素看作字典的key,如果key不存在,value值设置为1,如果key存在,value设置为0 (翻转),最后统计value为1 的个数。

第二种方法:异或法。通过异或法,我们目前也只是消除了偶数次的值,最后的结果是两个奇数次的值的异或。将异或的结果与所有第position位为1 的数字异或,出现的结果一定是两个数中的一个

6.如何找出第k小的数 ([4,0,1,0,2,3] 第3小的元素是1)

第一种方法:排序法。采用最高效的方法,快速排序。

第二种方法:部分排序。第一次找出最小值,第二次在剩下的数中找出最小的,第k次遍历就能找到最小的了

第三种方法:类快速排序法。arr[low...high]中的第一个元素作为划分依据,然后将数组分为三个部分,小于等于它,它自己,比它大,如果小于它的数刚好有k-1个,那么它就是第k小的元素,如果大于k-1个,代表在左边,找第k小;如果大于k-1,代表在右边,找k-(i-low)-1 小元素。

扩展:o(N)查找数组的前k个,初始化前3名,r1,r2,r3 分别代表第一名,第二名,第三名 。如果新来的数字大于谁替换谁的位置。

7.如何求数组中两个元素的最小距离 (数组中含有重复元素,给定两个数字num1和num2,求出现的最小位置)。

第一种方法:双重遍历。外循环查找num1的值,内循环查找num2的值。

第二种方法:动态规划法。遇到num1,记录下标值,与num2的上次下标值进行相减;如果遇到num2,与num1的上次下标值进行相减,求min值

8.如何求解最小的三元组距离 (已知三个升序数组,请在三个数组中各选择一个数字组成三元组的距离最小,三元数组的定义是D = max(|a-b|,|b-c|,|a-c|))

首先每一个数组都取第一个元素, 然后计算距离,然后再找到三个数中最小的那一个,往后移动一位,再次寻找最小值。

9.如何求数组中绝对值最小的数字 (一个升序排列的数组,数组中可能有正数,有负数,还有0)

如果第一个数是正数,那么最小值就是第一个数,如果第一个数是负数,那么最小的值就是最后一个数。又有正数又有负数,就可以找到临界点。可以通过二分法找临界点,如果中间这个值是0,那么就是最小的值;如果这个数大于0,比它小的数也大于0,那么最小值就在左边;如果这个数小于0,比它大的数也小于0,那么就是在右边。递归找

10.如何求数组连续最大值 (数组[1,-2,4,8,-4,7,-1,-5] 中,最大和的子数组为[4,8,-4,7])

定义一个和,首先等于第一个数,再定义一个变量,从第二个数进行遍历,用和去加这个变量,如果结果小于0,那么和置0;如果结果大于0,比较结果与原来的和,如果大于,就更新和,如果小于,就不变,继续往下运行。

13. 如何在不排序的情况下求数组的中位数

类快速排序的方法,类似与找第k大的值。pos大于一半,那么在左边,等于,就是,小于,在右边。

14.如何求集合的所有子集 (两个元素<a,b>,全部子集为<a,ab,b>)

第一种方法:位图法,模拟数组加一;使用非递归的思想,如果位数对应位1,就输出,否则就不输出。

第二种方法:迭代法。每一次迭代,都是上一次的迭代结果+上一次迭代中的每一个元素加上当前迭代的元素+当前迭代的元素。

15.如何对数组进行循环位移 

翻转法,前半段翻转,后半段翻转,合起来再翻转

16.如何在有规律的二维数组中进行高效的数据查找。

在有序的数组中进行查找,二分法是一个很不错的选择。

17.寻找最多的覆盖点 (一根长为L的木棍,最多能够覆盖多少坐标轴的多少点)

假设两个点分别为j 和 i,满足条件a[j]-a[i] < L && a[j+1] - a[i] > L,并且j - i 最大。首先定义i是最开始的一点,j往后增大,直到超过L, 这时候将i+1,j从当前位置继续加

18.如何判断请求能够在给定的储存条件下完成 (计算占R, 储存占O)

按照R-Q的大小进行排序,从大到小进行处理。

22.如何从3个有序数组中找出它们的公共元素

可以充分使用有序这个条件,如果a<b,a中的数据后移,如果b<c,那么b的数据后移, 否则,c的数据后移。有点类似最小的距离,都是最小的数据后移。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值