LeetCode 704 二分查找
题目:给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
二分查找是在有序表中按值查找一个元素。区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。
1.左闭右闭即[left, right]
while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=。
if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1。
int search(int* nums, int numsSize, int target) {
int left=0,right=numsSize-1;
while(left<=right){
int mid=(right+left)/2;
if(nums[mid]>target){
right=mid-1;
}else if(nums[mid]<target){
left=mid+1;
}else{
return mid;
}
}
return -1;
}
2左闭右开即[left, right)
int search(int* nums, int numsSize, int target) {
int left=0,right=numsSize-1;//开区间right所指的值不包含在区间中
while(left<right){//left与right相等无意义
int mid=(right+left)/2;
if(nums[mid]>target){
right=mid;//开区间此处mid不包含在区间中
}else if(nums[mid]<target){
left=mid+1;//left所指的值包含在区间中
}else{
return mid;
}
}
return -1;
}
Leetcode 27 移除元素
题目:
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
1.暴力解法
用i位置后面的元素向前移动一格,对i所在的值进行覆盖。注意!不要忘记覆盖之后要将i的值减一,因为当前位置已经被后面的数覆盖,需要重新验证。最后返回size数组的长度。
int removeElement(int* nums, int numsSize, int val) {
int size=numsSize;//用一个变量动态维护数组的长度
for(int i=0;i<size;i++){
if(nums[i]==val){
for(int j=i;j<size-1;++j){
nums[j]=nums[j+1];
}
i--;//因为下标i以后的数都向前移动了一格,故i也需要向前移动一位
size--;
}
}
return size;
}
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
2.双指针法
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针
- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
- 慢指针:指向更新 新数组下标的位置
int removeElement(int* nums, int numsSize, int val) {
int slow=0,fast=0;//slow指新数组的下标,fast则用于查找新数组的元素
while(fast<numsSize){
if(nums[fast]!=val){//此时将fast所指的值赋给slow位置,并让slow后移
nums[slow]=nums[fast];
slow++;
}
fast++;//fast始终后移
}
return slow;
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)