请实现有重复数字的升序数组的二分查找
给定一个 元素有序的(升序)长度为n的整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的第一个出现的target,如果目标值存在返回下标,否则返回 -1
数据范围:
进阶:时间复杂度
,空间复杂度%5C)
[1,2,4,4,5],4
2
从左到右,查找到第1个为4的,下标为2,返回2
[1,2,4,4,5],3
-1
[1,1,1,1,1],1
0
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 如果目标值存在返回下标,否则返回 -1
* @param nums int整型一维数组
* @param target int整型
* @return int整型
*/
public int search (int[] nums, int target) {
// write code here
if (nums == null || nums.length == 0) {
return -1;
}
int left = 0;
int right = nums.length - 1;
while (left < right - 1) {
int m = left + (right - left) / 2;
if (nums[m] == target) {
right = m;
} else if (nums[m] < target) {
left = m + 1;
} else {
right = m - 1;
}
}
if (nums[left] == target) {
return left;
}
if (nums[right] == target) {
return right;
}
return -1;
}
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 如果目标值存在返回下标,否则返回 -1
* @param nums int整型一维数组
* @param target int整型
* @return int整型
*/
public int search (int[] nums, int target) {
// write code here
if(nums == null || nums.length == 0) return -1;
int mid = nums.length / 2;
if (nums[mid] >= target){
for(int i=0;i <= mid;i++) if(nums[i] == target) return i;
} else {
for(int i=mid;i < nums.length;i++) if(nums[i] == target) return i;
}
return -1;
}
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 如果目标值存在返回下标,否则返回 -1
* @param nums int整型一维数组
* @param target int整型
* @return int整型
*/
public int search(int[] nums, int target) {
// write code here
// 1. 找中间值,和target进行比对
// 2. 中间值>= target :-> right = middle
// 3. 中间值< target :-> left = middle +1;
// 4. left == right 时,nums[middle] == target是第一个值为target的目标值
// 5. 否则,不存在该值,返回-1
int res = -1;
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int middle = left + ((right - left) >> 1);
// 左右相等,属于算到最后
if (left == right ) {
// 此时,如果一致,说明数组存在目标值,且找到最左侧的该值
if (nums[middle] != target) {
return -1;
}
//不一致,说明不存在该target
return left;
}
if (nums[middle] >= target) {
right = middle;
} else {
left = middle + 1;
}
}
return res;
}
}
public int search (int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] >= target) {
right = mid - 1;
}
}
if (left == nums.length) {
return -1;
}
// 直接返回
return nums[left] == target ? left : -1;
} public int search (int[] nums, int target) {
int low = 0;
int high = nums.length - 1;
int mid;
while(low <= high) {
mid = (low + high) / 2;
if(nums[mid] == target) {
for(int i = mid - 1; i >= 0; i--) {
if(nums[mid] != nums[i]) {
return i + 1;
}
}
return 0;
} else if(target > nums[mid]) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1;
}
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 如果目标值存在返回下标,否则返回 -1
* @param nums int整型一维数组
* @param target int整型
* @return int整型
*/
public int search (int[] nums, int target) {
// write code here
if(nums == null || nums.length == 0) {
return -1;
}
int left = 0, right = nums.length - 1;
while(left <= right) {
//注意mid的求法
int mid = left + (right - left) >> 1;
//注意中间元素与目标元素比较
if(nums[mid] >= target) {
right = mid - 1;
} else {
left = mid + 1;
}
if(nums[left] == target) {
return left;
}
//不要忘记累加操作
left++;
right++;
}
return -1;
}
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 如果目标值存在返回下标,否则返回 -1
* @param nums int整型一维数组
* @param target int整型
* @return int整型
*/
public int search (int[] nums, int target) {
// write code here
for(int i=0;i<nums.length;i++){
if(nums[i]==target){
return i;
}
}
return -1;
}
} public class Solution {
// [1, 2, 4, 3, 5]
public int search (int[] nums, int target) {
if (nums == null || nums.length == 0) {
return -1;
}
int left = 0, right = nums.length - 1;
while (left < right) {
// int mid = left + right / 2 此种用***超时
int mid = left + right >> 1;
if (nums[mid] >= target) {
right = mid;
} else {
left = mid + 1;
}
}
if (nums[left] == target) {
return left;
} else {
return -1;
}
}
} 思路:利用while循环,设置左右指针left,right。跳出循环的条件为left>right。mid = (left + right) / 2; 当中间值大于target,将left指针设置为mid + 1。当中间值小于target,将right指针设置为mid - 1;
当找到和target值相同的值时,需要遍历前面是否有相同的值,最小的为所要求的结果。单循环条件一定要注意加上mid <= 1。
public int search (int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = (right + left) / 2;
if (nums[mid] == target) {
while (mid >= 1 && nums[mid] == nums[mid - 1]) {
mid--;
}
return mid;
} else if (nums[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}