一、二分查找(leetcode704)
题目:给定一个
n
个元素有序的(升序)整型数组nums
和一个目标值target
,写一个函数搜索nums
中的target
,如果目标值存在返回下标,否则返回-1
。
1. 二分查找的前提是已经排序好的数组
2. while的判断条件在于是闭闭(<=),还是闭开区间(<)
- 如果是闭闭,right = mid -1
- 如果是闭开,right = mid
public static int ReturnBinarySearchIndex(int [] nums,int target){ // 二分查找 int left = 0; int right = nums.length -1 ; int mid; while(left <= right){ mid = (left + right ) / 2; if(nums[mid] < target){ left = mid + 1; } if(nums[mid] > target){ right = mid -1; } if(nums[mid] == target){ return mid; } } return -1; }
二、数组的删除(leetcode24)
题目:给你一个数组
nums
和一个值val
,你需要 原地 移除所有数值等于val
的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用
O(1)
额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
1. 注意事项:
- 数组的删除并不是真正的删除,而是被重新赋值了
- 数组的长度也并不是有多少数据就是有多长,而是可以根据自己来定义的
2. 三种方法
- 暴力破解
- 快慢指针法
- 双指针法
/**
* 由于数组是连续的,不能删除,所以删除只能通过重新赋值来实现"删除"
*
* @param nums
* @param val
* @return
*/
public static int removeElement(int[] nums, int val) {
if (nums == null || nums.length == 0) {
return 0;
}
int length = nums.length; // 实际的数组长度
for (int i = 0; i < length; i++) {
if (nums[i] == val) {
for (int j = i + 1; j < length; j++) {
nums[j - 1] = nums[j];
}
i--; // 指向删除位置的前一个位置,因为后面的数提前了一位,并且执行这段代码后i会+1
length--; // 删除了一个元素,实际长度-1
}
}
return length;
}
/**
* 利用快慢指针,通过直接赋值的手段简化了删除所需的移位操作
* @param nums
* @param val
* @return
*/
public static int removeElement01(int[] nums, int val) {
int fast;
int slow = 0;
for (fast = 0; fast < nums.length; fast++) {
if (nums[fast] != val) {
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
/**
* 双相指针法,利用左右两个指针,将右边的值赋给左边
* @param nums
* @param val
* @return
*/
public static int removeElement02(int [] nums, int val){
int left = 0;
int right = nums.length - 1;
while(left <= right){
if(nums[left] == val){
nums[left] = nums[right];
right--;
}else {
// 这里兼容了right指针指向的值与val相等的情况
left++;
}
}
return left;
}
}