704.二分查找
代码示例
class Solution {
public int search(int[] nums, int target) {
int low = 0;
int high = nums.length - 1;
while (low <= high) {
int mid = (low + high) >> 1;
if (nums[mid] == target) {
return mid;
}
if (nums[mid] < target) {
low = mid + 1;
}
if (nums[mid] > target) {
high = mid - 1;
}
}
return -1;
}
}
心得体会
1.。
int mid = low + (low + high) >> 1;
int mid = (low + high) >> 1;
使用代码1会优于代码2,因为不用考虑数值过大溢出的问题;
2.如图代码为左闭右闭区间,左右为数组两端,需要注意后面low与high分别需要加减1
如果代码为左闭右开区间,则代码如下:
class Solution {
public int search(int[] nums, int target) {
int low = 0;
int high = nums.length;
while (low < high) {
int mid = low + (low + high) >> 1;
if (nums[mid] == target) {
return mid;
}
if (nums[mid] < target) {
low = mid + 1;
}
if (nums[mid] > target) {
high = mid;
}
}
return -1;
}
}
此时不仅需要注意while中low<high以及high最后直接赋值mid即可,还需注意为high赋初值时应取nums.length,以使数组最后一个元素能够被搜索到。
35.搜索插入位置
代码示例
class Solution {
public int searchInsert(int[] nums, int target) {
int i;
for(i = 0; i <= nums.length -1; i ++){
if (nums[i] == target){
return i;
} else {
if (nums[i] > target){
break;
}
}
}
return i;
}
}
class Solution {
public int searchInsert(int[] nums, int target) {
if(nums.length == 0){
return 0;
}
int left = 0;
int rigth = nums.length -1;
while(left <= rigth){
int mid = left + (rigth - left) / 2;
if(nums[mid] == target){
return mid;
}else if(nums[mid] < target){
left = mid + 1;
}else{
rigth = mid - 1;
}
}
return left;
}
}
心得体会
1.上述代码中第一个为最初自己写的版本,下面为标答,可以看出二者最大的差别为是否使用二分法,事实证明,二分法确实比暴力搜索更快更省内存;
2.思路如下:
(1)搜索数组中是否有目标值,若有,直接输出其位置
(2)若数组中没有目标值,则可根据该数组为从小到大排序,用</<=判断目标值在数组中应占据的位置
27.移除元素
代码示例
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
for (int fast =0; fast <= nums.length - 1; fast ++){
if (nums[fast] != val){
nums[slow] = nums[fast];
slow ++;
}
}
return slow;
}
}
心得体会
本题为双指针,即指针一快一慢,当快指针搜索到目标值时,令慢指针停下,从而使二者之间有了差距,再将快指针后续搜索的值赋给慢指针,即可实现元素的移除
双指针的方法为逆向法,即正向思维为搜索到目标值,进行移除,而逆向思维为搜索非目标值,直接对目标值进行覆盖
p.s 元素的移除本质上是覆盖