704.二分查找下标
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。
👉🏻通过mid和target的位置关系缩小left到right的区间,最终使mid指向target
👉🏻确定区间,使用[left,right]还是[left,right)
👉🏻为什么要 mid=left+(right-left) / 2 : 因为当 (left+right)/2 时,left+right如果取到最大就超过了int范围
class Solution {
public int search(int[] nums, int target) {
if (target < nums[0] || target > nums[nums.length-1]){
return -1;
}
int left=0, right=nums.length-1;
while(left<=right){
int mid=left+(right-left) / 2;//防止溢出
if(nums[mid]==target){
return mid;
}else if(nums[mid]>target){
right=mid-1;
}else if(nums[mid]<target){
left=mid+1;
}
}
return -1;
}
}
27.移除元素
给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于val的元素,并返回移除后数组的新长度。
输入: nums = [3,2,2,3], val = 3
输出: 2, nums = [2,2]
数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
👉🏻快指针遍历,慢指针指向非val:
一堆萝卜连续种在地里,现在要将名字叫val的萝卜拔出,为保证连续,后面的萝卜要把val留下的坑补上。slow指向萝卜坑,fast负责依次寻找,每当坑和萝卜配对成功时slow就指向下一个坑,遇到val就把后一个不是val的萝卜放进val留下的坑里
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
for(int fast = 0; fast<nums.length; fast++){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
}
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情”