题目:
- 二分查找,27. 移除元素
学习内容:
704.二分查找
使用二分的前提:有序数组, 无重复元素。
二种方法:
- 左闭右闭
class Solution {
public int search(int[] nums, int target) {
// 检查target是否有在数组的可能性,避免多次循环
if (target < nums[0] || target > nums[nums.length - 1]) {
return -1;
}
int left = 0, right = nums.length - 1;
// 左闭右闭区间
while (left <= right) {
int mid = left + ((right - left) >> 1); // 右移一位等于除2,防止溢出
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else {
return mid;
}
}
return -1;
}
}
- 左闭右开
class Solution {
public int search(int[] nums, int target) {
if (target < nums[0] || target > nums[nums.length - 1]) {
return -1;
}
int left = 0, right = nums.length;
// 左闭右开
while (left < right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid; // 左闭右开
} else {
return mid;
}
}
return -1;
}
}
时间复杂度:O(logn)
空间复杂度:O(1)
拓展题:35.搜索插入位置,34. 在排序数组中查找元素的第一个和最后一个位置 (两次二分)
27.移除元素
- 暴力法
class Solution {
public int removeElement(int[] nums, int val) {
int size = nums.length;
for (int i = 0; i < size; i++) {
if (nums[i] == val) {
for (int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
i--;
size--;
}
}
return size;
}
}
时间复杂度:O(
n
2
n^2
n2)
空间复杂度:O(1)
- 双指针法(快慢指针)
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0; // 定义慢指针,慢指针是更新后数组的索引
//用快指针遍历
for (int fast = 0; fast < nums.length; fast++) {
// 若没有遇到需要删除的元素,则更新数组
if (nums[fast] != val) {
nums[slow] = nums[fast];
slow++;
}
}
return slow; // 返回数组新长度
}
}
学习时间:
2024.3.6