704.二分查找|27.移除元素【算法学习笔记】
- 二分查找法 通过与中间元素的比较判断目标元素在哪个区间,逐步缩小查找区间直至left=right,最后这个下标的元素就是我们要查找的值
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
if (target < nums[0] || target > nums[nums.length - 1]) {
return -1;}
while (left <= right) {
int middle = (left + right) / 2;
if (target < nums[middle]) {
right = middle - 1;
}
else if (target > nums[middle]) {
left = middle + 1;
}
else
return middle;
}
return -1;
}
- 移除元素 这道题的要求是在nums这个数组找到等于val的元素,并原地移除它
第一种解法是 暴力解法,通过第一次for循环遍历数组,再用一次for循环将后面的元素往前移,需要注意的第一点是在移动时到后面的元素不能越界,第二点是,移动后面的元素相当于i向前移动一位,需要i--,第三点是,size记得变化。
class Solution {
public int removeElement(int[] nums, int val) {
int size = nums.length;
for (int i = 0; i < size; i++) { //第一遍for循环遍历数组
if (nums[i] == val) { //遇到删除元素,删除它并且后面元素向前移动一位
for (int j = i+1 ; j < size; j++) {
nums[j-1] = nums[j];
}
i--; //i--保证下次循环依旧从删除位置开始
size--;
}
}
return size;
}
};
第二种解法是 双指针解法,又称快慢指针解法,慢指针指向要更新元素的位置,快指针指向用于替换旧元素的位置。
要理解的是区别于暴力解法,这个解法相当于用两个指针,当快指针没有遇到目标元素时,和慢指针一起前进,当遇到目标元素后就把快指针指向的元素赋给慢指针,这样就形成了一个错位,持续的更新数组元素,直到快指针指向最后一个元素,这时候慢指针指向的元素位置就是最后的长度。
class Solution {
public int removeElement(int[] nums, int val) {
// 快慢指针
int slowIndex = 0; //慢指针指向更新数组的位置
//快指针用来替换慢指针位置的元素
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
if (nums[fastIndex] != val) { //当遇到要删除的元素时,跳过,否则更新数组,慢指针+1
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
}