剑指 Offer 53 - I. 在排序数组中查找数字 I(34. 在排序数组中查找元素的第一个和最后一个位置)
题目:
思路:
【1】本身这道题单次遍历其实就能做出来,但是考察点在于能不能对O(N)的时间复杂度进行优化,毕竟是有序的,所以可以考虑二分查找的方式。
代码展示:
利用二分查找的方式:
//时间0 ms击败100% //内存44.4 MB击败44.65% //利用二分查找找到目标数字的下一个数字的开头 class Solution { public int search(int[] nums, int target) { return binarySearch(nums, target) - binarySearch(nums, target - 1); } public int binarySearch(int[] nums, int target) { int i = 0, j = nums.length - 1; while(i <= j) { int m = (i + j) / 2; if(nums[m] <= target) i = m + 1; else j = m - 1; } return i; } } //时间0 ms击败100% //内存44.7 MB击败50.30% //而对应找下标的话其实可以这样写, class Solution { public int[] searchRange(int[] nums, int target) { int leftIdx = binarySearch(nums, target-1); int rightIdx = binarySearch(nums, target) - 1; //确保能找出位置 if (leftIdx <= rightIdx) { return new int[]{leftIdx, rightIdx}; } return new int[]{-1, -1}; } public int binarySearch(int[] nums, int target) { int i = 0, j = nums.length - 1; while(i <= j) { int m = (i + j) / 2; if(nums[m] <= target) i = m + 1; else j = m - 1; } return i; } }
两道题简单遍历处理的方式:
//时间0 ms击败100% //内存44.6 MB击败31.73% class Solution { public int search(int[] nums, int target) { int res = 0; for (int x : nums){ if (target == x) res++; } return res; } } //时间1 ms击败9.52% //内存45.1 MB击败5.25% class Solution { public int[] searchRange(int[] nums, int target) { int fIndex = -1,eIndex = -1; for (int i = 0; i< nums.length; i++){ if (fIndex < 0 && target == nums[i]) fIndex = i; if (target == nums[i]) eIndex = i; } return new int[]{fIndex,eIndex}; } }