1. 题目
2. 思路
(1) 普通遍历
- 直接从前向后遍历,统计target出现的次数,返回即可。
(2) 二分查找
- 利用二分查找快速找出任意一个target的下标,然后以此下标为基准,分别向前和向后统计target出现的次数,返回即可。
(3) 跳跃查找
- 与(2)的思路基本相同,用跳跃查找代替二分查找,快速找出任意一个target的下标。
3. 代码
public class Test {
public static void main(String[] args) {
}
}
class Solution {
public int search(int[] nums, int target) {
if (nums.length == 0 || target < nums[0] || target > nums[nums.length - 1]) {
return 0;
}
int count = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] < target) {
continue;
} else if (nums[i] == target) {
count++;
} else {
break;
}
}
return count;
}
}
class Solution1 {
public int search(int[] nums, int target) {
if (nums.length == 0 || target < nums[0] || target > nums[nums.length - 1]) {
return 0;
}
int index = binarySearch(nums, 0, nums.length - 1, target);
if (index == -1) {
return 0;
}
int count = 0;
for (int i = index; i >= 0; i--) {
if (nums[i] == target) {
count++;
} else {
break;
}
}
for (int i = index + 1; i < nums.length; i++) {
if (nums[i] == target) {
count++;
} else {
break;
}
}
return count;
}
private int binarySearch(int[] nums, int left, int right, int target) {
if (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
return binarySearch(nums, left, mid - 1, target);
} else {
return binarySearch(nums, mid + 1, right, target);
}
}
return -1;
}
}
class Solution2 {
public int search(int[] nums, int target) {
if (nums.length == 0 || target < nums[0] || target > nums[nums.length - 1]) {
return 0;
}
int index = skipSearch(nums, 0, nums.length - 1, target);
if (index == -1) {
return 0;
}
int count = 0;
for (int i = index; i >= 0; i--) {
if (nums[i] == target) {
count++;
} else {
break;
}
}
for (int i = index + 1; i < nums.length; i++) {
if (nums[i] == target) {
count++;
} else {
break;
}
}
return count;
}
private int skipSearch(int[] nums, int left, int right, int target) {
if (nums[left] == target) {
return left;
}
if (nums[right] == target) {
return right;
}
if (left <= right) {
int newLeft = left + 1;
int newRight = right - 1;
int skip = 1;
for (int i = left; i <= right; i += skip) {
if (nums[i] < target) {
skip *= 2;
} else if (nums[i] == target) {
return i;
} else {
newRight = i - 1;
break;
}
}
skip = 1;
for (int i = newRight; i >= left; i -= skip) {
if (nums[i] > target) {
skip *= 2;
} else if (nums[i] == target) {
return i;
} else {
newLeft = i + 1;
break;
}
}
return skipSearch(nums, newLeft, newRight, target);
}
return -1;
}
}