704. 二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
思路
因为是升序的队列,并且无重复元素,因此我们优先考虑二分查找法。 二分查找法需要注意的事项为区间,即是左闭右开还是左闭右闭。
左闭右开 即 【left, right), 左闭右闭即 【left, right】;
两者的区别在于有边界是否为数组的最后一个值。
当我们使用左闭右开时,我们应该使用 while (left < right),当右边界变更时使用 right = mid。
当我们使用左闭右闭时,我们应该使用 while (left <= right),当右边界变更时使用 right = mid - 1。
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + ((right - left)>>1 - 1);
if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
return mid;
}
}
return -1;
}
}
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
27. 移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
思路
因为要求 仅使用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];
}
}
return slow;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)