第一章 数组
1.1 数组在内存中的存储方式
数组是存放在连续内存空间上的相同类型数据的集合。
- 数组下标从0开始
- 数组的内存空间地址是连续的
- 数组的元素不能删,只能移动
- 二维数组在c++中是连续的,在Java中是无规律分布的
704.二分查找
- 解题主要思想:有序数组且无重复元素可以使用二分法,在有序的数组里每次缩小一半范围,重复直到找到目标值
- 主要难点:在左右标志数设置的时候可以选择左闭右边闭也可以选择左闭右开,两种不同设置规则对应代码一些地方不同,均需满足循环不变量原则,使得下标对应的数值唯一确定。
- 左闭右闭:
- 左右标签:因为是左右闭合区间,所有右侧标签设置为数组长度-1
- 循环条件:在此情况下左标签与右标签相等是有意义的,所以设定为L<=R
- 区间更新:当通过判断目标元素与当前区间段中位数nums[M]大小来缩小区间范围时,更新左右标签值的方式需要注意,取右边区间更新左侧标签值的时候两种方法是一样的,都是L = M + 1,但是当取左侧区间需要更新右侧标签值的时候不同,因为这里右边是闭区间,且当前的nums[M]一定不是target,所以右标签需要设置为R = M - 1。
- 左闭右开:
- 左右标签:因为右开,所以右边标签初始值直接设置为数组长度即可
- 循环条件:因为当L=R时,[L,R)是无效空间,所以循环条件应该设为L<R
- 区间更新:取左侧区间需要更新右侧标签值时,因为现在是右开区间,因此直接将R = M就可以
- 左闭右闭:
- 其他注意事项:
- 在设置完左右标签初始值,准备设置初始中间值M的时候,直接用(L +R)/ 2可能溢出,所以使用M = L + (R - L) / 2的方式。
- 上面的写法还可以改为M = L + (R - L) >> 1,这种写法使用到了二进制右移的方式,也就是>>符号,其作用和除2是一样的,因为L+R 在某种情况下可能会超过基本类型所能容纳的最大值,而且使用>> (位运算) 比 / 运算要更快。
27.移除元素
- 解题主要思想:双指针(快慢指针法),快指针先移动,当快指针对应的数值与所要找的val值不一样的时候,将快指针的值赋给慢指针,同时慢指针向前移动一位,循环直到将整个数组完成替换。
- 主要难点:快慢指针的思想,使用一个for循环完成两个for循环的工作,提升时间复杂度为O(n)