704. Binary Search
参考视频和详解:代码随想录
代码实现:
1.初始化指针
left = 0
right = size- 1(左闭右闭)
right = size (左闭右开)
2.while循环
while(left <= right) 左闭右闭
while(left < right) 左闭右开
3.求middle
int middle = left + (right - left) / 2;
4.二分法
4.1 左闭右闭写法 [left, right]
if(nums[middle] > target){
right = middle - 1
//if条件中已经明确middle > target,说明 middle不在左闭右闭的合法区间内,所以这里的right应该middle-1, 而不是等于middle
}else if (nums[middle] < target){
left = middle + 1 //同理,这里也是middle +1
}else{
return middle
}
return -1
4.2 左闭右开写法 [left, right)
if(num[middle] > target){
right = middle //if条件中明确了middle > target,说明middle不在合法区间内。因为是合法区间是左闭右开的区间,right也不在合法区间内,所以middle可以等于right
}else if(num[middle] < target){
left = middle + 1 //if条件中明确了middle < target,说明middle不在合法区间内,但是合法区间是左闭的,会包含left,所以left应该middle+1
}else{
return middle
}
return -1
错误原因
1.middle没有放进while循环里
2.middle公式错误
3.一开始没有对target的值进行合法性校验。
遇到的问题
1.数组个数分奇偶,会有小数,不知道怎么求middle
✅实际上不用担心小数问题,因为java除法会对小数自动向下取整,left + (right - left) / 2 在执行时总是会返回一个整数
2 .target合法性校验
✅不能写成以下,因为nums[nums.length]已经数组越界
if(target < nums[0] || target >= nums[nums.length]){
return -1;
}
总结:
边界的规则是根据区间的定义来的
[左闭右闭]
while(left <= right)
left = middle + 1
right = middle - 1
[左闭右开]
while(left < right)
left = middle + 1
right = middle
27. Remove Element
参考视频和详解
思路
用快慢指针完成两个for循环
- 快指针:寻找新数组元素
- 慢指针:更新新数组下标位置
代码实现
1. 定义快慢指针
slow = 0
2. 用快指针遍历数组
for(int fast = 0; fast < nums[].length; i++)
3. 寻找新数组元素(即数组中不等于val的元素)
if(nums[fast] != val)
4. 让慢指针指向新数组元素
nums[slow] = nums[fast]
5. 指针后移
slow++
(fast在for循环中++)
6. 返回新数组元素个数
return slow
遇到的问题
- 没有理解快慢指针的作用
- 没有想到把fast指针的移动放在for循环中,而是在代码块中进行fast++,增加了代码复杂度
- 判断是不是新数组元素出错,条件写成 if(nums[fast] == val)。恰恰相反,只有不等于val时才放进新数组
- 返回时出错。新数组的size应该返回slow,而不是slow+1,因为当完成最后一个元素的遍历时,slow已经多加了一个,刚好为size