代码随想录算法Day01-二分查找、移除元素、有序数组的平方
二分查找
- 二分查找的区间:左闭右闭、左闭右开
- 循环不变量:在循环遍历的时候,这个区间一开始是什么样的开闭状态,后面就是什么样的开闭状态
- 实践:
- 如果是左闭右闭,while终止条件是left <= right,left=right有意义,
right=nums.length-1,相当于右边界是可能包含target的,所以如果nums[middle]>target,那么right=middle-1。 - 如果是左闭右开,while终止条件是left<right,因为left=right是没有意义的,
right=nums.length,右边界是不包含target的,所以如果nums[middle]>target,那么right=middle,因为middle正好是无意义的,另一种情况,left=middle-1,因为left是包含target的。
- 如果是左闭右闭,while终止条件是left <= right,left=right有意义,
- 左闭右开代码:
public int findTarget(int[] nums,int target){
int left = 0;
int right = nums.length;
while(left<right){
int middle = (left + right)/2;
if(nums[middle] == target) {
return middle;
} else if(nums[middle] > target){
right = middle;
} else {
left = middle + 1;
}
}
return -1;
}
移除元素
- 移除元素其实就是
remove()方法的实现,不是把target给删掉就行了,而是将目标值删除之后,还要将后面的元素都移到前面 - 我们可以这样理解,抽象成一个原数组,一个新数组,如果当前元素不等于目标值,就放入新数组。
- 但是这个题目不能用额外的空间,一个数组怎么实现两个数组的作用呢,使用双指针的方法:快指针用来遍历数组,慢指针用来充当新数组。
public int remove(int[] nums,int target) {
int slow = 0;
for(int fast = 0;fast<nums.length-1;fast++){
if(nums[fast] != target) {
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
有序数组的平方
- 如果没有复杂度的限制,直接算出来所有元素的平方在,再排序,如果用快排的话,时间复杂度为O(nlogn)。
- 这里采用双指针的方法,一个有序数组带负数,他的元素平方的最大值肯定是分布在两端,所以我们只需要写两个指针,遍历原数组,并将结果写到另一个结果数组当中即可。
public int[] sortedSquares(int[] nums) {
int[] res = new int[nums.length];
int left = 0;
int right = nums.length-1;
for(int i = 0;i < nums.length-1;i++){
if(Math.abs(nums[left])>Math.abs(nums[right])){
res[nums.length-1-i] = nums[left] * nums[left];
left++;
} else {
res[nums.length-1-i] = nums[right]*nums[right];
right--;
}
}
return res;
}
今天主要做的是简单的数组题,二分查找和双指针相关
浙公网安备 33010602011771号