请实现有重复数字的升序数组的二分查找
给定一个 元素有序的(升序)长度为n的整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的第一个出现的target,如果目标值存在返回下标,否则返回 -1
数据范围:
进阶:时间复杂度,空间复杂度
[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 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; }
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 int low = 0,high = nums.length-1; int index = -1; while(low <= high){ // int mid = low + (high - low) / 2; if(nums[low] == target){ index = low; break; }else if(nums[low] < target){ low++; }else { high--; } } return index; } }