704. 二分查找
注意点:
1、二分法的前提是有序数组。
2、题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的(这是我没想到的地方)
收获:
例如到底是 while(left < right) 还是 while(left <= right),到底是right = middle呢,还是要right = middle - 1呢?
对区间的定义没有想清楚,区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作
感觉自己比较喜欢左闭右闭的写法
C代码:(左闭右开)
// [left,right)
// 左闭右开,寻找的条件一定是left<right,没有=
// 如果nums[mid]<target,说明应该往右边[X,right] 往右边因为mid已经参与过比较了 所以X(left)=mid+1
// 如果nums[mid]>target,说明应该往左边[left,X) 同意mid已经参与过比较了,但因为是开的,所以X(right) = mid即可
int search(int* nums, int numsSize, int target){
int left = 0;
int right = numsSize;
int mid;
while(left<right){
mid = left+(right-left)/2; //防止溢出
if(nums[mid]==target){
return mid;
}
else if(nums[mid]<target){
left = mid+1;
}
else{
// right = mid-1 ;
// 一开始提交不通过,因为写成了上面这样
right = mid;
}
}
return -1;
}
C代码:(左闭右闭)
int search(int* nums, int numsSize, int target){
int left = 0;
int right = numsSize-1;
int mid;
while(left<=right){
mid = left+(right-left)/2; //防止溢出
if(nums[mid]==target){
return mid;
}
else if(nums[mid]<target){
left = mid+1;
}
else{
right = mid-1;
}
}
return -1;
}
Python(左闭右闭)
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0,len(nums)-1
while left<=right:
middle = left + (right-left)//2
if nums[middle] == target:
return middle
elif nums[middle] > target:
right = middle - 1
else:
left = middle + 1
return -1
27. 移除元素
有点儿忙,先简单写下,应该还可以优化
// 从index=0往后遍历,遇到值不等于val的,就把他放到index位置
int removeElement(int* nums, int numsSize, int val){
int index = 0;
for(int i=0;i<numsSize;i++){
if(nums[i]!=val){
nums[index] = nums[i];
index++;
}
}
return index;
}
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
index = 0
for i in range(len(nums)):
if(nums[i]!=val):
nums[index] = nums[i]
index += 1
return index