数组是存放在连续内存空间上的相同类型数据的集合。
数组可以方便的通过下标索引的方式获取到下标下对应的数据。
举一个字符数组的例子,如图所示:
数组可以方便的通过下标索引的方式获取到下标下对应的数据。
举一个字符数组的例子,如图所示:

需要两点注意的是
vector的底层实现是array,严格来讲vector是容器,不是数组。
C++数据结构——array、vector、链表_c++ array和vector_菜鸟知识搬运工的博客-CSDN博客
第一种写法,我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right] (这个很重要非常重要)。
区间的定义这就决定了二分法的代码应该如何写,因为定义target在[left, right]区间,所以有如下两点:
很多同学这道题目做的很懵,就是不理解 快慢指针究竟都是什么含义,所以一定要明确含义,后面的思路就更容易理解了。
删除过程如下:

- class Solution {
- public:
- int search(vector<int>& nums, int target) {
- int left = 0;
- int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
- while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=
- int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
- if (nums[middle] > target) {
- right = middle - 1; // target 在左区间,所以[left, middle - 1]
- } else if (nums[middle] < target) {
- left = middle + 1; // target 在右区间,所以[middle + 1, right]
- } else { // nums[middle] == target
- return middle; // 数组中找到目标值,直接返回下标
- }
- }
- // 未找到目标值
- return -1;
- }
- };
如果说定义 target 是在一个在左闭右开的区间里,也就是[left, right) ,那么二分法的边界处理方式则截然不同。
有如下两点:

- class Solution {
- public:
- int search(vector<int>& nums, int target) {
- int left = 0;
- int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)
- while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
- int middle = left + ((right - left) >> 1);
- if (nums[middle] > target) {
- right = middle; // target 在左区间,在[left, middle)中
- } else if (nums[middle] < target) {
- left = middle + 1; // target 在右区间,在[middle + 1, right)中
- } else { // nums[middle] == target
- return middle; // 数组中找到目标值,直接返回下标
- }
- }
- // 未找到目标值
- return -1;
- }
- };
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针