Leecode 704. 二分查找(要掌握 二分法是面试常考题
看到题目的第一想法
数组有序且无重复元素 考虑是否可以使用二分法
二分查找,先定义初始区间,然后进行区间更新,不断比较nums[mid]和target的值
看完代码随想录之后的想法
- 注意区间:
- 左闭右闭区间
- 初始化: left = 0; right = nums.length - 1; while(left <= right)
- 更新区间 :left = mid + 1; right = mid - 1; - 左闭右开区间
- 初始化:left = 0; right = nums.length; while(left < right)
- 更新区间 left = mid + 1; right = mid;
- 左闭右闭区间
综上,二者的区别在于右区间right的初始化和更新
自己实现过程中遇到哪些困难
区间更新不太明确
mid定义在了while外面导致没有更新,代码出错
今日收获
- 对二分法中区间的更新过程理解更加清晰
- int mid = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
// An highlighted block
// 时间复杂度:O(log n)
// 空间复杂度:O(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) / 2);// 防止溢出 等同于(left + right)/2
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target){
right = mid - 1;
}else{
left = mid + 1;
}
}
return -1;
}
}
Leecode 35. 搜索插入位置
题目链接:35. 搜索插入位置
自己实现过程中遇到哪些困难
如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
这种情况不知道如何处理
// 704题目代码中最后一行的 return -1; 改为 return right + 1;
// 其他代码完全相同
Leecode 34. 在排序数组中查找元素的第一个和最后一个位置
自己实现过程中遇到哪些困难
想法:找到一个目标值后向左向右遍历是否有和目标值相等的值,结果超时。
查看题解后优化代码,用2次二分查找来实现
// 两次二分查找
class Solution {
public int[] searchRange(int[] nums, int target) {
int first = -1; // 初始化左右边界
int last = -1; // 初始化左右边界
// 找第一个等于target的位置
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
if(nums[mid] == target){
first = mid;
right = mid - 1; // 在target左边进行二分查找
}else if(nums[mid] > target){
right = mid - 1;
}else{
left = mid + 1;
}
}
// 最后一个等于target的位置
left = 0;
right = nums.length - 1;
while(left <= right){
int mid = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
if(nums[mid] == target){
last = mid;
left = mid + 1; // 在target右边进行二分查找
}else if(nums[mid] > target){
right = mid - 1;
}else{
left = mid + 1;
}
}
return new int[]{first, last};
}
}
Leecode 27. 移除元素(要掌握
题目链接:27 移除元素
文章讲解:移除元素
视频讲解:b站移除元素
状态: 通过
题目建议: **暴力的解法,可以锻炼一下我们的代码实现能力,建议先把暴力写法写一遍。 双指针法 是本题的精髓,今日需要掌握,至于拓展题目可以先不看。 **
自己实现过程中遇到哪些困难
用快慢指针实现,不清楚快指针和慢指针分别代表什么
看完代码随想录之后的想法
快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
慢指针:指向更新 新数组下标的位置
今日收获
熟悉了快慢指针的应用和数组相关操作
// 快慢指针
class Solution {
public int removeElement(int[] nums, int val) {
int slowIndex = 0;
for(int fastIndex = 0; fastIndex < nums.length; fastIndex++){
if(nums[fastIndex] != val){
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
}
// 暴力解法 2次for
class Solution {
public int removeElement(int[] nums, int val) {
int len = nums.length;
for(int i = 0; i < len; i++){
if(nums[i] == val){
for(int j = i + 1; j < len; j++){
nums[j - 1] = nums[j];
}
i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
len--; // 此时数组的大小-1
}
}
return len;
}
}