704. 二分查找
题目链接:https://leetcode.cn/problems/binary-search/description/
解题思路
二分查找条件判断:有序数组、数组元素不重复
如果数组中的元素可能重复,那查找出来的值可能不唯一。
这道题主要是对于二分查找的区间定义,区间定义主要分为两种,左闭右闭 即[left, right],左闭右开 即[left, right)。
下面是两种写法的代码实现
左闭右闭
注意点:当 nums[mid] > target 时,right = mid - 1; 因为左闭右闭表示 left和 right 对应的值都可能是target,而 nums[mid] 已经确定不是target了,所以 right = mid - 1;
class Solution {
public int search(int[] nums, int target) {
// 特殊条件判断
if (nums == null || nums.length == 0 || nums[0] > target || nums[nums.length-1] < target) {
return -1;
}
int left = 0;
int right = nums.length - 1;
while(left <= right) {
int mid = left + ((right - left) >> 1); // 防止溢出
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
}
左闭右开
注意点:当 nums[mid] > target 时,right = mid;
class Solution {
public int search(int[] nums, int target) {
// 特殊条件判断
if (nums == null || nums.length == 0 || nums[0] > target || nums[nums.length-1] < target) {
return -1;
}
int left = 0;
int right = nums.length;
while (left < right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
right = mid;
} else {
left = mid + 1;
}
}
return -1;
}
}
27. 移除元素
题目链接:https://leetcode.cn/problems/binary-search/description/
解题思路
这道题我一开始的思路是使用另一个数组来存储不等于val的数据(汗颜,忽略了原地移除这个条件)。写到最后发现,新数组根本不需要,直接用传入的数组就可以了。这种写法也就是双指针法
双指针法
定义一个快指针,一个慢指针。快指针指向当前正在被遍历的数组的下标位置,慢指针指向新数组的下标位置,通过判断快指针指向的值是否等于val,来将快指针对应的值覆盖到慢指针。
代码如下:
class Solution {
public int removeElement(int[] nums, int val) {
if (nums.length == 0) {
return 0 ;
}
// 新建一个数组保存不等于val的数据
int[] rtn = new int[nums.length]; // 不需要
int index = 0; // 慢指针,指向新数组的最新位置
for (int num : nums) { // 快指针,用于遍历数组
if (num != val) {
nums[index++] = num;
}
}
return index;
}
}
977. 有序数组的平方
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/description/
解题思路
因为是一个非递减的排序数组,如果数组全是正整数,那平方后的最大值只可能在最右边,但是有负数,所以平方后的最大值可能在最左边或最右边,那就可以双指针法
双指针法
定义一个数组,存储平方后的值,并定义一个下标指针,指向该数组的最大值,也就是最右边的值。
定义一个左指针,指向从左到右的数组下标。定义一个右指针,指向从右向左的数组下标。
如果左指针指向的值的平方大于右指针指向的值的平方,则左指针加一,反之则右指针减一。并将较大的那个值存到返回数组中。
代码如下:
class Solution {
public int[] sortedSquares(int[] nums) {
// 新建一个数组来存储返回值
int [] ret = new int[nums.length];
int index = nums.length-1;
int left = 0;
int right = index;
while(left <= right) {
int leftValue = nums[left] * nums[left];
int rightValue = nums[right] * nums[right];
if (leftValue > rightValue) {
ret[index--] = leftValue;
left++;
} else {
ret[index--] = rightValue;
right--;
}
}
return ret;
}
}