题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
解题思路:
解法一:直接从前往后搜索,时间复杂度O(n)
AC代码:
class Solution {public boolean search(int[] nums, int target) {for (int num : nums) {if (num == target) {return true;}}return false;}
}
解法二:二分查找
因为有序数组nums预先是在k位置进行了旋转,那么对于任意一个下标 i ,会将nums分为左半部分和右半部分,那么左半部分和右半部分一定是一个有序,一个无序的。所以如果能够确定哪一部分有序,那么就可以在有序的那一部分使用二分查找。
确定那一部分有序:对于下标 left ,mid,right,将nums分为两部分nums[left,mid],nums[mid,right]
- 如果nums[left] < nums[mid],说明左半部分有序
- 否则,即nums[mid]<nums[right],说明右半部分有序
- 但是有种特殊情况,判断不出哪一部分是否有序,那就是nums[left] == nums[mid]这种情况,比如 [ 1,0,1,1,1 ],当 left =0,mid = 2时,此时nums[left] == nums[mid],此时如果出现这种情况,就令 left++,将最左边重复的那一项去掉,直到不会出现nums[left] != nums[mid],这个时候,就可以判断出那一部分有序,之后就一直在有序的那一部分进行二分查找
AC代码:
class Solution {public boolean search(int[] nums, int target) {int left = 0;int right = nums.length;while (left < right) {int mid = left + (right - left) / 2;if (nums[mid] == target) {return true;}//此时判断不出那一部分有序,令left++,去除重复项if (nums[left] == nums[mid]) {left++;continue;}if (nums[left] < nums[mid]) {//左半部分有序//target在左部分中if (nums[left] <= target && nums[mid] > target) {right = mid;}else {//在右半部分中left=mid+1;}}else {//右半部分有序//在右半部分中if (nums[mid]<target&&nums[right-1]>=target){left = mid+1;}else {//在作伴部分中right =mid;}}}return false;}
}
不过这种解法在最坏情况下的时间复杂度和方法一相同,都为O(n)