LeetCode704.二分查找
```java
package com.liqi.day.day1;
public class LeeCode_704 { //704.二分查找 注意使用二分查找的前提条件是 有序+没有重复元素
public static void main(String[] args) {
int[] nums = {1, 3, 6, 8, 9, 10, 12, 90, 40, 59};
int search = search(nums, 12);
System.out.println(search);
}
public static int search(int[] nums, int target) {//todo 二刷的时候使用左闭右开来写
// 避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算
if (target < nums[0] || target > nums[nums.length - 1]) {
return -1;
}
int left = 0;
int right = nums.length - 1;
while (left <= right) {//这里注意边界问题,因为我们定义的区间是左闭右闭
// ,也就是两个边界的值都能取得到,假设当left=right 1时,二分出来的子区间为[1,1]是一个合法的区间,所以left可以等于right
int middle = (left + right) / 2;
if (target > nums[middle]) {//目标值在右区间,所以需要二分缩小右边界在右边查找,这里也要注意边界问题,为什么left不能直接取middle?
//原因分析:因为我们已经确定了target>nums[middle],所以此时这个nums[middle]不应该存在于下个子区间内,而我们的区间左边是闭着的去得到,所以是middle+1
left = middle + 1;
continue;
}
if (target < nums[middle]) {//目标值在左区间,所以需要二分缩小左边界在左边查找,这里也要注意边界问题:
// 为什么不能直接取middle? 与上面同理,右边是闭着得也取得到,但是把nums[middle]带到下个子区间内又没有意义,所以是middle-1
right = middle - 1;
continue;
}
return middle;
}
return -1;
}
}
LeetCode27.移除元素
两种解法:
1.双指针(最优解,时间复杂度o(n)
public static int removeElement(int[] nums, int val) {
int slow = 0;
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
if (nums[fastIndex] != val) {
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
2.双层for循环遍历:一个for循环遍历数组元素 ,第二个for循环更新数组。
## 收获总结:
1. 使用二分查找法的前提是有序+元素不重复,有序不用多说,元素重复的话会导致满足条件的index不止一个,然后的话就是学会了如何处理二分查找中的边界情况(根据原区间是如何定义的然后假设left等于right时子区间是否是一个合法的区间)
2. 加深了对数组这个数据结构的理解,因为数组是内存中地址连续的数据结构,所以对数组进行添加或者删除只能重新new一个数组然后进行拷贝,**而移除元素这道题规定不能new数组,所以我们可以用双指针的思想去模拟两个数组,slowindex代表新数组的下标,fastindex代表旧数组下标,这样去想这道题很容易就能通过双指针去解决。**