704. 二分查找
题目:给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
解答思路:1.暴力 2.二分查找
这里因为是升序数组,使用二分查找:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0, right=nums.size()-1,middle=-1;
while(left<=right){
middle = (left+right)/2;
if(target<nums[middle]){
right = middle-1;
}
else if(target>nums[middle]){
left = middle+1;
}
else{
return middle;
}
}
return -1;
}
};
使用二分查找的思想是对搜索区间进行二分,每次迭代使得搜索区间变为原来的一半,区间缩小的方式为对半二分,在区间缩小时要注意最后找到值或者迭代到区间不能二分为止。
所以代码结构为:
while(区间中至少有一个元素){
1.取区间中点(若没命中,将决定下次区间搜索的边界,命中则返回值);
2.判断目标值与区间中点值的关系;
3.缩小区间:
3.1( if(target<nums[middle])则区间旋转左边的一半,处理端点时,
由于是用的左闭右闭的方式,新的区间中不应该包含nums[middle],
因为这个值一定不是目标值,所以更新区间的右边界时舍弃这个点right = middle-1;)
3.2同理如果target>nums[middle]类似;
3.3 如果命中,则之间返回该值;
4.持续循环下去
}
循环内部若没有返回,说明没有找到。return -1;
题目:给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
解决思路:快慢双指针法,实现原地遍历,在原地建立一个符合题意的新数组,快指针负责先行遍历数组元素,选出符合要求的元素给慢指针使用,慢指针负责使用快指针所提供的值来建立新数组。由于快指针是每轮循环都走一次,慢指针只有在快指针找到符合要求的数值之后才会走,不是符合要求的数一定不会超过原数组数量,所以慢指针一定不会超过快指针,不会出现数据被意外覆写的情况。
代码如下:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slow = 0;
for(int ifast=0;ifast<nums.size();ifast++){
if(nums[ifast]!=val) nums[slow++]=nums[ifast];
}
return slow;
}
由于最后一次更新慢指针的值之后,慢指针仍然++,指向了尾后元素,所以其索引就是最后新数组的长度。