数组——LEETCODE的第35题(二分法与lower_bound函数)
本文主要是根据leetcode 35题所写的关于数组的相关内容,主要包括:
- 数组的的特性
- leetcode第35题二分法的解题
- lower_bound函数的使用
文章目录
- 数组——LEETCODE的第35题(二分法与lower_bound函数)
- 一、数组
- 1.1 注意事项
- 1.2 数组的应用方法
- 二、数组的二分法
- 2.1 何为二分法
- 2.2 二分法解题1
- 2.3 lower_bound函数
一、数组
数组是一种数据结构,它可以存储一系列相同类型的元素,并通过索引来访问这些元素。在C++中,数组是一种非常基本且常用的数据类型,它具有以下特点:
-
相同类型的元素:数组中的元素必须是相同类型的。这意味着,如果你创建了一个整型数组,那么数组中的所有元素都必须是整数。
-
连续的内存空间:数组中的元素在内存中是连续存储的。这也意味着,数组的大小在创建时就已经确定,且不可变。
-
零基索引:在C++中,数组的索引是从零开始的。也就是说,第一个元素的索引是0,第二个是1,以此类推。
下面是一个简单的C++数组的声明和初始化示例:
#include <iostream>int main() {// 声明一个整型数组,大小为5int arr[5];// 初始化数组元素arr[0] = 10;arr[1] = 20;arr[2] = 30;arr[3] = 40;arr[4] = 50;// 访问数组元素并打印for (int i = 0; i < 5; ++i) {std::cout << "arr[" << i << "] = " << arr[i] << std::endl;}return 0;
}
1.1 注意事项
-
数组越界访问:在访问数组时一定要确保不要越界。如果访问了数组范围之外的元素,会导致未定义的行为,可能会导致程序崩溃或产生不可预测的结果。
-
数组大小:在声明数组时,必须指定数组的大小。这个大小在编译时必须是确定的,不能是变量或者动态分配的。如果需要动态大小的数组,应该使用动态分配的方式,比如使用
std::vector
。 -
内存占用:数组在内存中是连续存储的,因此如果数组元素占用的内存空间很大,数组可能会占用大量的内存。这在处理大型数据集时需要特别注意。
1.2 数组的应用方法
-
遍历数组:使用循环结构,如
for
或while
循环,可以遍历数组中的所有元素。 -
数组作为函数参数:可以将数组作为函数的参数传递。在传递数组时,通常会传递数组的指针以及数组的大小,以便函数能够正确地处理数组。
-
多维数组:C++支持多维数组,比如二维数组、三维数组等。多维数组在处理矩阵、图像等问题时非常有用。
-
数组和指针的关系:在C++中,数组名本身就是数组的地址,因此可以将数组名作为指针使用。这意味着,可以通过指针操作数组的元素。
-
标准库中的数组类:除了原生的数组,C++标准库中也提供了
std::array
容器类,它提供了更多的功能和安全性,比如可以获取数组的大小、迭代器等。 -
算法与数组:C++标准库提供了丰富的算法,可以用于处理数组,如排序、查找、操作等。
综上所述,数组是C++编程中非常基础和常用的数据结构,熟练掌握数组的使用方法以及注意事项对于编写高效、安全的程序至关重要。
二、数组的二分法
35.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
2.1 何为二分法
二分法(Binary Search)是一种在有序数组中查找特定元素的搜索算法。它的基本思想是每次将搜索区间减半,从而快速定位目标元素。
下面是二分法的基本步骤:
-
确定搜索区间:首先,确定整个有序数组作为搜索的初始区间。通常情况下,初始搜索区间是整个数组。
-
找到中间元素:计算搜索区间的中间位置,并将中间位置的元素与目标元素进行比较。
-
调整搜索区间:根据中间元素与目标元素的比较结果,调整搜索区间的范围。如果中间元素等于目标元素,搜索结束;如果中间元素大于目标元素,说明目标元素应该在中间元素的左侧,将搜索区间缩小为左半部分;如果中间元素小于目标元素,说明目标元素应该在中间元素的右侧,将搜索区间缩小为右半部分。
-
重复步骤2和3:根据目标元素与中间元素的比较结果,不断缩小搜索区间,直到找到目标元素或搜索区间为空。
下面是一个简单的示例代码,演示了如何使用二分法在有序数组中查找目标元素:
#include <iostream>
#include <vector>int binarySearch(const std::vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1;while (left <= right) {int middle = left + (right - left) / 2; // 防止整型溢出if (nums[middle] == target) {return middle; // 找到目标元素,返回索引位置} else if (nums[middle] < target) {left = middle + 1; // 目标元素在右侧,调整搜索区间为右半部分} else {right = middle - 1; // 目标元素在左侧,调整搜索区间为左半部分}}return -1; // 目标元素不存在,返回 -1
}int main() {std::vector<int> nums = {1, 3, 5, 7, 9, 11, 13};int target = 7;int result = binarySearch(nums, target);if (result != -1) {std::cout << "Target found at index " << result << std::endl;} else {std::cout << "Target not found" << std::endl;}return 0;
}
在这个示例中,我们定义了一个 binarySearch
函数来执行二分查找。首先,我们将整个有序数组作为初始搜索区间。然后,通过不断调整搜索区间的范围,最终找到目标元素的索引位置或者确定目标元素不存在。
2.2 二分法解题1
对于力扣35题,可以使用简单的二分法进行解题,
class Solution {
public:int searchInsert(vector<int>& nums, int target) {int front = 0;int rear = nums.size() - 1; // 使用nums.size()获取vector中的元素个数while (front <= rear) {int middle = front + ((rear - front) >> 1);if (nums[middle] > target) {rear = middle - 1;} else if (nums[middle] < target) {front = middle + 1;} else {return middle;}}return front; // 返回插入位置}
};
很简答的一个解法,但是还有一个C++的库可以提供更简单的使用方法
2.3 lower_bound函数
return lower_bound(nums.begin(),nums.end(),target) - nums.begin();
std::lower_bound
函数是 C++ 标准库 <algorithm>
头文件中的一个函数,用于在已排序的序列中查找第一个不小于给定值的元素。它返回一个迭代器,指向第一个不小于目标值的元素。
std::lower_bound
函数的声明如下:
template< class ForwardIt, class T >
ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T& value);
这个函数用于在有序序列中查找第一个不小于给定值的元素,并返回指向该元素的迭代器。以下是函数的参数解析:
first
:表示搜索范围的起始位置的迭代器。last
:表示搜索范围的结束位置的迭代器。注意,该位置不包含在搜索范围内。value
:表示要查找的目标值。
函数将返回一个迭代器,指向序列中第一个不小于目标值的元素,或者如果所有元素都小于目标值,则返回 last
。
在代码中,lower_bound(nums.begin(), nums.end(), target)
返回一个迭代器,指向 nums
中第一个不小于 target
的元素。然后,通过减去 nums.begin()
,我们得到了这个迭代器相对于 nums.begin()
的偏移量,也就是元素的索引位置。
需要注意的是,如果目标值存在于序列中,lower_bound
返回的是第一个不小于目标值的元素的迭代器,而不是目标值本身的迭代器。因此,如果要返回目标值在序列中的确切位置,还需要对返回的迭代器进行进一步的判断。
以下是一个示例代码:
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> nums = {1, 3, 5, 7, 9};int target = 6;int insertPosition = std::lower_bound(nums.begin(), nums.end(), target) - nums.begin();std::cout << "Insert position for " << target << " is: " << insertPosition << std::endl;return 0;
}
输出将会是:Insert position for 6 is: 3
这表明对于值为6的元素,应该插入到索引位置3的位置上,也就是在元素7之前。