代码随想录-数组1
704. 二分查找
基本思路
设定左右边界,找到中间值,根据中间值判断目标元素所在范围,更新边界。
二分法(左闭右闭)
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
int m = left + (right - left) / 2;
while(left <= right){
m = left + (right - left) / 2;
if(nums[m] == target){
return m;
}else if(nums[m] < target){
left = m + 1;
}else{
right = m - 1;
}
}
return -1;
}
}
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
注意点
- 循环判断条件会影响边界更新方法
while(left <= right)条件下,right = middle - 1,left=mid+1while(left < right)条件下,right = middle,left=mid+1
- 计算中间下标的方法:
| 实现 | 适用场合 | 可能出现的问题 |
|---|---|---|
| mid=(left+right)/2 | left>=0,right>=0,left+right无溢出 | left+right可能溢出。负数情况下有向0取整的问题 |
| mid=(left+right)>>1 | left-right无溢出 | 若right、left都是大数且一正一负,right-left可能溢出 |
| mid=left+(right-left)/2 | left+right无溢出 | 若right、left都是大数,left+right可能溢出。 |
27. 移除元素
基本思路
双指针法,同向双指针和相向双指针。不考虑顺序也不考虑后面超出新数组长度的元素,利用左侧指针找到目标值所在下标,把右侧指针的值赋给左侧指针位置(注意不是交换)。都没有判断右侧指针的值是否是目标值,因为左侧指针在更新之前都会先确保指向的值不是目标值。
同向指针(快慢指针)
- 快指针:寻找新数组的元素
- 慢指针:指向需要更新的目标元素位置
class Solution {
public int removeElement(int[] nums, int val) {
int left = 0;
int right = 0;
//也可以理解为,right遍历数组,left用来记录等于val的位置
//遍历一次就完成
while(right < nums.length){
if(nums[right] != val){
nums[left] = nums[right];
left++;
}
right++;
}
return left;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)
相向指针
- 左侧指针:找到需要更新的位置
- 右侧指针:新数组元素
class Solution {
public int removeElement(int[] nums, int val) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
if (nums[left] == val) {
// 直接赋值就好,不用交换
// 也不用判断右边是否为val,因为进入这个if之后,left不会更新
// 下次判断的还是这个left,但是right会自动更新
nums[left] = nums[right];
right--;
} else {
left++;
}
}
return left;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)
注意点
第一个同向指针法没改变元素的相对位置,相向指针法改变了相对位置

浙公网安备 33010602011771号