算法基础(2)

249 阅读3分钟

1.认识二分法

普通二分法是在一堆有序的数中找一个数,比如[1,3,5,6,7],我要你找出3这个数,你会这么操作,首先找到[1,3,5,6,7]中间的那个数也就是5,你将其和3比较发现不相等,于是你找[1,3,5]中间的那个数也就是3,你将其和3比较发现相等,于是找到了,这就是普通的二分法找数。

当然这是一种思想,他可以变形。
变形1:

比如我现在给你一组有序的数,让你找到这组数的左边第一个和我给你的数相等的数。举个具体的例子: [1,3,3,6,7],我给你这个数是3,你会这么操作,首先找到[1,3,3,6,7]中间的那个数也就是3,你和3比较发现他和3相等,你会继续往左,找到[1,3,3]中间的那个数,又和3相等,你继续往左,发现1和3不相等,于是最左边的3就是第二个数。

变形2:

我现在定义一个局部最小,如果他比他左边相邻的数小,也比他右边相邻的数小则是局部最小,如果是头尾,则只要比相邻的数小就是局部最小。现在要你在一组无序的数里找出一个局部最小的数。你会这么操作,首先找到第一个位置的数,你将他和第二个位置的数比较,如果第一个位置的数小你就找到了,如果第一个位置大,你知道他的趋势是下降的趋势。然后你又会找到最后一个位置的数,你将他和倒数第二位置的数比较,如果最后一个位置的数小你就找到了,如果最后一个位置的数比倒数第一个位置的数大你就知道趋势是上升的趋势。结合下降和上升你知道中间肯定存在局部最小的数,于是你看了下这组数中间的数,如果你比两边都小你就找到了,如果他比左边大,那么趋势是上升趋势,你知道0-中间这个数中间肯定有一个数是局部最小的数。依次类推。

2.认识异或操作

异或操作书里说是将两个数变成二进制的数,然后相同为0,不同为1。其实你就记住异或操作是两个二进制数没有进位的加法就好了。

那么你就会得出两个结论,0和任何一个数异或都会是这个数本身,两个相同的数异或结果是0。

利用这两个结论你就可以做一些异或的题目了。

1.给你一组数告诉你其中只有一个数出现奇数次,找出这个数

你肯定会想,我拿0和这组数做异或操作不就好了,0 ^ A ^ A ^ B,消消乐,偶数个A异或为0,0和任意数异或还是那个数,于是B被找到。

2.如何不引入第三个变量,交换a和b的值

你肯定会想, a = 10, b = 10,交换他们的值, a = a ^ b,b = a ^ b,由于a = a ^ b, 这样b = a ^ b ^ b = a,你再a = a ^ b,这时的b已经是a了,于是 a = a ^ b ^ a = b,成功交换。

3.给你一个数,找到这个数二进制位左边第一个为1的位置。

你肯定会想,一个数,二进制先假设他是 00001000010,然后取反变成11110111101,然后再加上1,变成11110111110,然后将这个数和之前的数做与操作,得到00000000010,这样就得到最左边的1了。