三刷代码随想录的目标:
1.题目思考要有自主性。
直接自己做,做出来用注释标出关键点。做不出来看题解,抓住问题的关键。
2.题目关键点、原理及拓展尽可能遍历到。
是区间、边界等细节问题?还是原理、方法问题?
3.做所学知识做总结。
抓住关键点
// 关键点:区间定义左闭右闭。目的是将落单的元素也能遍历到!!!
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) { // 之所以是≤,是为了保证范围内的最后一个元素也能被获取到
int mid = (left + right) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] < target) {
left = mid + 1;
}
}
return -1; // 都不满足则将-1作为默认结果返回
}
}
// 模板一样,仅仅将默认输出结果-1变为l(代表"left")!!!
class Solution {
public int searchInsert(int[] nums, int target) {
int l = 0;
int r = nums.length - 1;
int mid = 0;
while (l <= r) { // 左闭右闭区间
mid = (l + r) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
r = mid - 1;
} else {
l = mid + 1;
}
}
return l; // 拿example2模拟一下就是这个结果
}
}
34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)
// 二分法的模板下,遇到相等元素时,以此索引为基准分别前后进行遍历,获取区间内值相同的前后两个索引加入到结果集ans中!!!
class Solution {
public int[] searchRange(int[] nums, int target) {
int[] res = {-1, -1};
int left = 0;
int right = nums.length - 1;
int[] ans = new int[2];
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == target) { // 当遇到相同元素时,分别向前向后进行遍历,直到不满足条件。
int index = mid;
while (--index >=0 && nums[index] == target) {
continue;
}
ans[0] = index + 1; // 第一相等值的索引
while (++mid < nums.length && nums[mid] == target) {
continue;
}
ans[1] = mid - 1; // 最后相等值的索引
return ans;
} else if (nums[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return res;
}
}
题解一:这题看着竟然有点懵,本质就是遇到(!=val)的元素就执行覆盖操作,否则向后遍历即可。
题解二:遇到(==val)的元素就执行覆盖操作,否则循环遍历即可。
// 从前向后遍历和覆盖
// class Solution {
// public int removeElement(int[] nums, int val) {
// int left = 0;
// for (int right = 0; right < nums.length; right++) {
// if (nums[right] != val) { // 区别点
// nums[left] = nums[right];
// left++;
// }
// }
// return left;
// }
// }
// 从后向前向后遍历,从后向前覆盖
class Solution {
public int removeElement(int[] nums, int val) {
int left = 0, right = nums.length - 1;
while (left <= right) {
if (nums[left] == val) { // 区别点
nums[left] = nums[right];
right--;
} else {
left++;
}
}
return left;
}
}