LeetCode.704
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
主要思考while循环是是否带等号,左闭右闭 需要带等号,左闭右开 不需要等号
/**
* 左闭右闭
* @param nums
* @param target
* @return
*/
public static int search(int[] nums, int target) {
int result = -1; // 目标值下标,没有则返回 -1
int left = 0; // 坐标起点
int right = nums.length - 1; // 使用左闭右闭原则 右边起点为 length - 1
while (left <= right) { // 因为是[left, right] 所以要使用 <= 不然会遗漏一个值
int middle = ((right - left) / 2) + left;
if (nums[middle] < target) {
// middle的值已经明确比target小,所以直接从middle下一位开始比较
left = middle + 1;
} else if (nums[middle] > target) {
// middle已经明确比target大,所以直接对比middle前一位
right = middle - 1;
} else {
// middle位的值等于target,直接返回
return middle;
}
}
return result;
}
/**
* 左闭右开
* @param nums
* @param target
* @return
*/
public static int search1(int[] nums, int target) {
int result = -1; // 目标值下标,没有则返回 -1
int left = 0; // 坐标起点
int right = nums.length; // 使用左闭右开原则 右边起点为 length
while (left < right) { // 因为是[left, right) 所以要使用 < 不然会会数组越界
int middle = ((right - left) / 2) + left;
if (nums[middle] < target) {
// middle的值已经明确比target小,所以直接从middle下一位开始比较
left = middle + 1;
} else if (nums[middle] > target) {
// 因为是左闭右开,所以不包括middle那个位置,right 直接等于middle
right = middle;
} else {
// middle位的值等于target,直接返回
return middle;
}
}
return result;
}
LeetCode.27
/**
* 暴力算法,时间复杂度O(n^2)
* @param nums
* @param val
* @return
*/
public static int removeElementForBF(int[] nums, int val) {
int len = nums.length;
for (int i = 0; i < len; i++) {
if (nums[i] == val) {
//发现目标元素,后面的整体往前移动
for (int j = i; j < nums.length - 1; j++) {
nums[j] = nums[j + 1];
}
i--; //删除一个元素后,需要从当前位置开始遍历,由于for循环会+1 所有提前减掉
len--; // 删除一个元素后,长度-1
}
}
return len;
}
/**
* 双指针写法 时间复杂度O(n)
* @param nums
* @param val
* @return
*/
public static int removeElementForDoublePointer(int[] nums, int val) {
//双指针写法
int slow = 0;
for (int fast = 0; fast < nums.length; fast++) {
if (nums[fast] != val) {
nums[slow++] = nums[fast]; //先执行赋值操作,后执行++
}
}
return slow;
}