目录
27 移除元素
不难想到暴力方法,通过新开辟数组在循环中进行判断,如果不为val值就加入新数组。时间复杂度O(n),空间复杂度O(n)。
由于题目规定必须仅使用
O(1)
额外空间并原地输入修改数组,我们可以通过快慢指针法进行优化,快指针对整个nums数组进行遍历,慢指针记录满足条件不等于val的数字,最后当快指针完成遍历后返回慢指针。
class Solution {
public int removeElement(int[] nums, int val) {
int l = 0,r = 0;
for(;r < nums.length;r++){
if(nums[r] != val){
nums[l++] = nums[r];
}
}
return l;
}
}
时间复杂度O(n),空间复杂度O(1)。
704 二分查找
当在一个升序(或者降序)数组nums中查找指定值target时,可以通过二分查找的方式优化。
易知在一个升(降)序数组中如果nums[i]==target,则下标i即为要寻找的下标;
如果nums[i]>target,则 target只可能在下标i的左(右)侧;
如果nums[i]<target,则 target\textit{target}target 只可能在下标i的右(左)侧。
定义int mid = (r - l ) / 2 + l 并逐步更新mid使之接近目标target,每次查找都会将查找范围缩小一半,降低了时间复杂度。
左闭右开[l,r)
class Solution {
public int search(int[] nums, int target) {
int l = 0,r = nums.length;//因为为左闭右开,所以r取nums.length
while(l < r){//左闭右开,l != r 举例 [1,1)
int mid = (r - l) / 2 + l;//避免越界
if(nums[mid] > target)r = mid;//左闭右开,mid不是我们想搜索的值,不用+1
else if(nums[mid] < target)l = mid + 1;//左闭右开,mid不是我们想搜索的值,需要+1
else{return mid;}
}
return -1;
}
}
时间复杂度O(logn),空间复杂度O(1)。
左闭右闭[l,r]
class Solution {
public int search(int[] nums, int target) {
int l = 0,r = nums.length - 1;//因为为左闭右闭,r取nums.length - 1
while(l <= r){//左闭右闭,l 可以等于 r 举例 [1,1]
int mid = (r - l ) / 2 + l;
if(nums[mid] == target)return mid;
if(nums[mid] > target)r = mid - 1;//左闭右闭,mid不是我们想搜索的值
else if(nums[mid] < target)l = mid + 1;//左闭右闭,mid不是我们想搜索的值
else return mid;
}
return -1;
}
}
时间复杂度O(logn),空间复杂度O(1)。