704. 二分查找
题目描述:给定一个
n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1
- 左闭右闭区间
class Solution {
public int search(int[] nums, int target) {
int start=0,end=nums.length-1;
int middle=0;
//start和end都指向nums的有效下标,在不断二分过程中,start始终比end小
//直到start==end,即同时指向同一个位置的元素时,进行最后一次比较
while(start<=end){
//start和end的中间
middle=(start+end)>>1;
if(nums[middle]==target){
return middle;
}else if(nums[middle]>target){
end=middle-1;
}else{
start=middle+1;
}
}
return -1;
}
}
示意图如下:
- 情形1:找得到target
-
情形2:找不到target
- 左闭右开区间:
class Solution {
public int search(int[] nums, int target) {
int start=0,end=nums.length;
int middle=0;
while(start<end){
middle=(start+end)>>1;
if(nums[middle]==target){
return middle;
}else if(nums[middle]>target){
end=middle;
}else{
start=middle+1;
}
}
return -1;
}
}
左闭右闭(下面简称为:one:)和左闭右开(下面简称为:two:)的区别:
- 循环终止条件不同::one:的循环条件
start>=end,:two:的循环条件start>end,因为在:two:中,end所指向的元素不在此次查找范围内,因此查找过程中start!=endend的移动不同:在查找中,每轮被比较对象nums[middle]在下一软中都不在查找序列中, :one:中end始终指向待查询序列的最后一个位置,因此当end需要移动时,会移动到middle-1的位置;而:two:中end始终指向待查询序列的最后一个位置的下一个位置,此位置必然不在待查询序列中,因此当end需要移动时,移动到middle的位置即可。
27.移除元素
题目描述:给你一个数组
nums和一个值val,你需要 原地 移除所有数值等于val的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用
O(1)额外空间并 原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
暴力解法
思路:
题目要求原地移除元素,因此不能额外借用其他数组或容器来存储结果。
暴力解法对给出的nums数组进行遍历,将每个元素都与val比较,当二者值相同时,将该元素后的所有元素向前移动一格,数组末元素的下标减1。
我们使用end记录数组末尾元素的下标,当发生移动时,即是将[nums[i+1],nums[end-1]]的元素移动到[nums[i],nums[end-2]]中。
在方法返回时,end就是结果数组的长度,返回即可。
一次数组元素的移动如图:
class Solution {
//暴力方法
public int removeElement(int[] nums, int val) {
int end=nums.length;
for(int i=0;i<end;i++){
if(nums[i]==val){
//向前移动[nums[i+1],nums[end-1]]的元素到[nums[i],nums[end-2]]
for(int j=i+1;j<end;j++){
nums[j-1]=nums[j];
}
end--;
i--;
}
}
return end;
}
}
双指针法
思路:使用快慢指针fast和slow对给定数组nums进行操作,其中,fast对数组进行遍历,slow从数组下标为0处依次记录fast在遍历中不为target(代码中该变量为val)的数组元素。当fast完成一次遍历后,slow指向的位置不再记录新的元素,因此,slow的值即为结果数组的长度。
class Solution {
//双指针方法
public int removeElement(int[] nums, int val) {
int slow=0,fast=0;
while(fast<nums.length){
if(nums[fast]!=val){
nums[slow]=nums[fast];
slow++;
}
fast++;
}
return slow;
}
}