魔术索引
方法一:暴力搜索
遍历一遍数组,如果$nums[i]=i$就返回,否则返回-1。
1 | class Solution { |
2 | public int findMagicIndex(int[] nums) { |
3 | for(int i=0; i<nums.length; i++){ |
4 | if(nums[i] == i){ |
5 | return i; |
6 | } |
7 | } |
8 | return -1; |
9 | } |
10 | } |
复杂度分析:
- 时间复杂度:$O(n)$。
- 空间复杂度:$O(1)$。
方法二:二分查找
由于存在重复元素,因此不能简单的二分查找。我们先将数组一分为二,先查找左半部分,如果左半部分有满足条件的,就返回索引。如果没有,就看$nums[mid]$是否等于$mid$,如果等于,就返回$mid$,否则就去右半部分查找,过程和上面的一样,因此可以用递归来实现。
1 | class Solution { |
2 | public int findMagicIndex(int[] nums) { |
3 | return getAnswer(nums, 0, nums.length-1); |
4 | } |
5 | |
6 | public int getAnswer(int[] nums, int left, int right){ |
7 | int mid = left + (right-left)/2; |
8 | if(left > right){ |
9 | return -1; |
10 | } |
11 | int leftAnswer = getAnswer(nums, left, mid-1); |
12 | if(leftAnswer != -1){ |
13 | return leftAnswer; |
14 | }else if(mid == nums[mid]){ |
15 | return mid; |
16 | } |
17 | return getAnswer(nums, mid+1, right); |
18 | } |
19 | } |
复杂度分析:
- 时间复杂度:$O(n)$,最坏情况下会达到$O(n)$。
- 空间复杂度:$O(n)$,最坏情况下递归n层。