leetcode算法练习
704.二分查找
思路:已经排好序 设置left mid right三根指针 根据mid指向的值和target目标值进行大小判断来决定left right指针的移动
注意点:
1. while中(left < 还是 < = right)
2. 循环里 right = mid 还是 = mid -1
3. 选取范围是[left, right] 还是 [left, right)
要根据3选取的范围是[left, right] 还是 [left, right) 来决定 1,2两点
方法一:左闭右闭[left, right]区间
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
// 考虑到while的区间应该是合法的 那么在 闭区间[left, right] 中:left == right 是合法的 既然合法就要在while中进行判断 故应该是 while(left <= right)
while(left <= right){
// 为防止越界
int mid = left + (right - left) / 2;
if(target == nums[mid]){
return mid;
}else if(target > nums[mid]){
// 原理同下
left = mid + 1;
}else if(target < nums[mid]){
// 考虑到现在是 闭区间[left, right]中 已经判断过nums[mid] > target 那么mid一定不是要搜索的值 那么接下来的区间 一定不要包含 mid 这个值 既然不包含 那么接下来的区间应该是[left,mid-1] 不能把不在查找范围里的值包括进去
right = mid - 1;
}
}
return -1;
}
}
方法二:左闭右开[left, right)区间
class Solution {
public int search(int[] nums, int target) {
int left = 0;
// 不包含右边界
int right = nums.length;
// 在左闭右开区间[left, right)中 left == right 是不合法的 故在while中应该是<
while(left < right){
int mid = left + (right - left) / 2;
if(target == nums[mid]){
return mid;
}else if(target > nums[mid]){
// 左闭右开区间[left, right) 包含left 现在已经明确了mid不是target 那么下一个搜索区间就不能包括mid 所以left = mid + 1
left = mid + 1;
}else if(target < nums[mid]){
// 考虑到现在是 左闭右开区间[left, right)中 即不包含right 那么下一个区间应该不包含mid所在的数值 所以right = mid
right = mid;
}
}
return -1;
}
}
27. 移除元素
思路:
暴力解法:找到需要移除的元素 把后面的元素都往前移
双指针:利用快慢指针来更新新数组
注意:
1. 暴力解法中:往前移动的元素 还是需要与target进行比较 否则就会出错
2. 双指针:理解快慢两个指针的作用
方法一:暴力解法
class Solution {
public int removeElement(int[] nums, int val) {
int len = nums.length;
for(int left = 0; left < len; left++){
if(nums[left] == val){
for(int right = left + 1; right < len; right++){
nums[left] = nums[right];
}
// 因为下标i以后的数值都向前移动了一位 所以i也向前移动一位 这样才不会漏判
left--;
len--;
}
}
return len;
}
}
方法二:双指针
快指针:寻找新数组(删除目标之后的元素组成的数组)所需要的元素
慢指针:新数组的下标值 即需要更新的下标
快指针取到的值赋值给慢指针即可
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;
}
}