数组理论基础
数组是存放在连续内存空间上的相同类型数据的集合。
需要注意的是
- 数组下标都是从0开始的。
- 数组内存空间的地址是连续的
正因为数组在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,难免要移动其他元素的地址。
总结
由于数组是紧凑连续存储,所以可以随机访问,通过索引快速找到对应元素,而且相对节约存储空间。但正因为连续存储,内存空间必须一次性分配够,如果需要扩容,需要重新分配一块更大的空间,再把数据复制过去,时间复杂度O(n)。如果想在数组中间进行插入和删除,每次必须搬移后面所有的数据以保持连续,时间复杂度O(n)。
704. 二分查找
思路
因为nums里面的数是不重复的,所以我们可以暴力解法,从第一个数查看,如果找到target的数,就返回它的index,如果没有找到,就返回-1。
更好的方法是用二分法。因为这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当看到题目描述满足如上条件的时候,就可以想一想是不是可以用二分法了。
计算mid时需要防止溢出,left + (right - left) / 2。防止left和right太大,直接相加会导致溢出。
区间的定义决定了二分法的代码应该如何写,因为定义target在[left, right]区间(左闭右闭),所以有如下两点:
- while (left <= right) 要使用 <= ,因为left == right是有意义的。
- if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的右区间下标位置就是 middle - 1。
- if (nums[middle] < target) left 要赋值为 middle + 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间下标位置就是 middle + 1。
27. 移除元素
思路
因为数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
暴力解法就是两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针
- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
- 慢指针:指向更新 新数组下标的位置