leetcode 704. 二分查找、 27. 移除元素。
leecode 704 二分查找
题目链接 :https://leetcode.cn/problems/binary-search/description/
解题思路
这道题就是常规的二分查找算法的应用,对于二分查找,相对比较难的地方就在边界值的判断了。一般来说,有两种写法,分别是[left,right]左闭右闭的原则,这时右边界的可以取到的,所以终止判断条件为lefe <= right。另外在收缩边界范围时if(nums[mid] >target) ,right = mid - 1,因为nums[mid]是可以取到且不等于target,右边界要往左边收缩,即right = mid - 1.。具体实现代码:
public int search(int[] nums, int target) {
int left = 0; //左边界
int right = nums.length - 1; // 右边界
while(left <= right) { //终止条件为left = right + 1 这也是35.搜索插入位置题目的解题关键
int mid = left + (right - left) / 2;
System.out.println(nums[mid]);
if(nums[mid] == target){
return mid; //找到target,返回所在小标
}else if(nums[mid] > target) {
right = mid - 1; //target在区间[left,mid - 1]
}else{
left = mid + 1; //target在区间[mid + 1.right]
}
}
return -1; //找不到target
}
第二种是左闭右开原则[left,right),此时是取不到右边界nums[right]的,所以终止判断条件为left < reight,另外在收缩边界范围时if(nums[mid] >target) ,right = mid ,因为nums[mid]是已经比较完了,而在[left,right)区间上,是不会去去到nums[right]的,所以right = mid后,在进入下一个区间后是不会去比较num[mid],因为此时mid是等于right,处于右边界上,即[left,right),具体代码实现:
public int search(int[] nums, int target) {
int left = 0; //左边界
int right = nums.length; //左闭右开 [left, right)
while(left < right) {
int mid = left + (right - left) / 2;
System.out.println(nums[mid]);
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target) {
right = mid; //target在区间[left,mid]
}else{
left = mid + 1; //target在区间[mid + 1.right]
}
}
return -1; //找不到target
}
知识点
二分查找算法的应用
注意事项
左闭右闭和左闭右开边界值的判断,其实我们只需要掌握其中一种就可以了,这在leetcode34题体现的挺重要的。
相关题目
35.搜索插入位置
34.在排序数组中查找元素的第一个和最后一个位置
leecode 27 移除元素
题目链接 :https://leetcode.cn/problems/remove-element/description/
解题思路
因为要求是在原地修改输入数组,所以不能新建另一个数组去完成。一般这类的,是使用双指针的思想。
初始化i和j指针为0,i指针记录当前指向非val值的位置,j指针遍历数组,当j指针的值nums[j]不等于val,则将num[j]赋值给nums[i] 并且i++,j++,而nums[j]等于val,则跳过,即j++,这样,当便利完这个nums数组后,i指针所走过的路程即为数组中非val的长度。具体实现代码为:
public int removeElement(int[] nums, int val) {
int i = 0;
int j = 0;
while(j < nums.length) {
if(nums[j] != val) {
nums[i++] = nums[j]; //nums[j]不等于val,则将num[j]赋值给nums[i],并且i++
}
j++; //继续便利
}
// for(int j = 0;j < nums.length; j++) {
// if(nums[j] != val) {
// nums[i++] = nums[j];
// }
// }
return i; //i即代表长度
}
知识点
双指针
注意事项
双指针分别开始的位置,和判断的条件以及长度的计算