1. 二分查找:
704. 二分查找 - 力扣(LeetCode)
对于二分查找的思想较为简单,具体如下:
假设寻找的值为,分别定义两个变量,其中,。
再定义一个变量,如果,表示需要查找的元素在数组的右半部分,此时需要更新,使得。如果,表示需要查找的数在数组的左半部分,此时需要更新,使得。
如果遇到的情况,说明在给定数组中成功的找到了,此时返回即可。
对于二分查找的结束判定条件,为。因此可以得出代码为:
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.移除元素:
27. 移除元素 - 力扣(LeetCode)
对于此题,文章提供两种解决方法,分别是暴力求解以及双指针法:
题目中要求,需要在不开辟额外空间的情况下,额外修改数组,删除数组中数值等于的元素。由于数组是一块连续空间,因此,在删除数组中的元素时,并不能直接进行删除,例如删除下列给出数组中值为的元素:
对于数组中的删除,其实是对于元素的覆盖,例如,删除上面数值为的元素,即:
对于上述过程 ,可以分为下面的情况:
首先建立循环,定义变量,变量用于检测数组中位置的元素是否等于,如果位置的元素的值等于,则进入第二层循环,在第二层循环中,定义变量,即:
随后,令位置及其之后的元素整体向前移动一位:
对于上述过程,看作一次移除元素,由于移除了一次元素,因此需要将数组的长度。
对于上面给出的例子,体现了一个特殊情况,即:两个值为的元素在数组中连续排列。但是由于上述移除元素的过程,将这些元素整体向前移动了一位,因此,为了针对这种特殊情况,需要将向前移动一位。对应代码如下:
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 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;
}
};