1. 二分查找:
对于二分查找的思想较为简单,具体如下:
假设寻找的值为,分别定义两个变量
,其中
,
。
再定义一个变量,如果
,表示需要查找的元素在数组的右半部分,此时需要更新
,使得
。如果
,表示需要查找的数在数组的左半部分,此时需要更新
,使得
。
如果遇到的情况,说明在给定数组中成功的找到了
,此时返回
即可。
对于二分查找的结束判定条件,为。因此可以得出代码为:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0,right = nums.size()-1;
while(left <= right)
{
int mid = (left+right)/2;
if(target > nums[mid])
{
left = mid+1;
}
else if(target < nums[mid])
{
right = mid-1;
}
else
{
return mid;
}
}
return -1;
}
};
2.移除元素:
对于此题,文章提供两种解决方法,分别是暴力求解以及双指针法:
题目中要求,需要在不开辟额外空间的情况下,额外修改数组,删除数组中数值等于的元素。由于数组是一块连续空间,因此,在删除数组中的元素时,并不能直接进行删除,例如删除下列给出数组中值为
的元素:
对于数组中的删除,其实是对于元素的覆盖,例如,删除上面数值为的元素,即:
对于上述过程 ,可以分为下面的情况:
首先建立循环,定义变量
,变量
用于检测数组中
位置的元素是否等于
,如果
位置的元素的值等于
,则进入第二层
循环,在第二层循环中,定义变量
,即:
随后,令位置及其之后的元素整体向前移动一位:
对于上述过程,看作一次移除元素,由于移除了一次元素,因此需要将数组的长度。
对于上面给出的例子,体现了一个特殊情况,即:两个值为的元素在数组中连续排列。但是由于上述移除元素的过程,将这些元素整体向前移动了一位,因此,为了针对这种特殊情况,需要将
向前移动一位。对应代码如下:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
for(int i = 0; i < size; i++)
{
if(nums[i] == val)
{
for(int j = i+1; j < size; j++)
{
nums[j-1] = nums[j];
}
size--;
i--;
}
}
return size;
}
};
在给出了暴力解法的代码后,此处引入第二种解法,即:双指针法。具体方法如下:
分别创建两个指针,对于两个指针,最开始都指向数组最开头的元素。
随后,首先让遍历数组,如果
位置所对应的元素不等于
,则对
位置的元素进行一次复写,在复写完成后,让
指向下一个位置。如果
位置所对应的元素等于
,则继续让
指向下一个位置。直到遇到的元素不等于
。为了更方便的理解上述过程,下面给出一个例子来进行演示:
在最开始,均指向元素
,由于元素
不是
,因此,
对
的元素进行原地复写,即:
此时,位置所对应的元素等于
,因此,
继续向后遍历
此时,位置所遇到的元素不等于
,即:
因此,对的位置进行复写,然后再让
指向下一个位置,即:
对于后续操作,均按照上述步骤执行。
对于上述操作,下面给出相应的代码,即:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
if (val != nums[fastIndex]) {
nums[slowIndex++] = nums[fastIndex];
}
}
return slowIndex;
}
};