704 二分查找
解题思路
- 这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素
- 区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)
- 我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right]
[left, right] 左闭右闭区间,确定while循环条件和边界调整
左闭右闭区间,[1, 1] 包含左右区间,因此while(left<=right),循环条件合法;
if(nums[middle]>target) ,target在左区间,已知左闭右闭区间,已知判断条件nums[middle]大于target,说明,nums[middle]一定不是搜索的值,所以接下来的区域一定不包含这个值,因此right = middle - 1;
同理,nums[middle]<nums[target],target在右区间,已知判断条件nums[middle]<target,说明,nums[middle]一定不是搜索的值,因此left = middle+1;
int letf = 0;
int right = nums.size()-1;
while(lef<=right)
{
int middle = (letf + 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; // 数组中找到目标值,直接返回下标
}
}
如果说定义 target 是在一个在左闭右开的区间里,也就是[left, right)
- while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]
int search(vector<int>& nums, int target) {
//1.[left, right)
int left = 0;//左区间
int right = nums.size();//右区间
while(left < right)
{
int middle = (left+right)/2;
if(nums[middle] > target)
{
right = middle;
}
else if(nums[middle] < target)
{
left = middle + 1;
}
else
{
return middle;
}
}
return -1;
}
27 移除元素
解题思路
- 双指针法
- 快指针:寻找符合条件的新数组的元素,新数组不含目标元素的数组
- 慢指针:更新新数组,将寻找到的元素更新到新的数组中,新数组下标的位置
- 暴力破解法
//双指针法
int removeElement(vector<int>& nums, int val) {
//慢指针
int slow = 0;
for(int fast = 0;fast<nums.size();fast++)
{
if(val!=nums[fast])
{
nums[slow++] = nums[fast];
}
}
return slow;
}
977 有序数组的平方
解题思路
- 双指针法
vector<int> sortedSquares(vector<int>& nums) {
//双指针法
int k = nums.size()-1;
int left = 0;
int right = nums.size()-1;
//新定义数组
vector<int> result(nums.size(), 0);
while(left<=right)
{
if(nums[left]*nums[left]>nums[right]*nums[right])
{
result[k--] = nums[left]*nums[left];
left++;
}else
{
result[k--] = nums[right]*nums[right];
right--;
}
}
return result;
}