2014-03-20 03:01

题目:给定一个已按升序排序的数组,找出是否有A[i] = i的情况出现。

解法1:如果元素不重复,是可以严格二分查找的。

代码:

 1 // 9.3 Given a unique sorted array, find a position where A[i] = i, if one exists.
 2 #include <cstdio>
 3 #include <vector>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     vector<int> v;
 9     int n;
10     int i;
11     int ll, rr, mm;
12     
13     while (scanf("%d", &n) == 1 && n > 0) {
14         v.resize(n);
15         for (i = 0; i < n; ++i) {
16             scanf("%d", &v[i]);
17         }
18         if (v[0] > 0 || v[n - 1] < n - 1) {
19             mm = -1;
20         } else {
21             ll = 0;
22             rr = n - 1;
23             while (ll <= rr) {
24                 mm = (ll + rr) / 2;
25                 if (v[mm] < mm) {
26                     ll = mm + 1;
27                 } else if (v[mm] > mm) {
28                     rr = mm - 1;
29                 } else {
30                     break;
31                 }
32             }
33             if (ll > rr) {
34                 mm = -1;
35             }
36         }
37         printf("%d\n", mm);
38         
39         v.clear();
40     }
41     
42     return 0;
43 }

解法2:如果元素可能存在重复,那么会出现无法确定答案在左边还是右边的时候。比如{-1, 3, 3, 3, 3},后面的连续4个‘3’中有A[i]<i,有A[i]>i,也有A[i]=i的。这种情况下就得两边都进行查找了。在没有重复的时候,还是可以二分的,因此总体复杂度介于O(log(n))和O(n)之间,依数据好坏而变。

代码:

 1 // 9.3 Given a sorted array, find a position where A[i] = i, if one exists. The array may have duplicates.
 2 #include <cstdio>
 3 #include <vector>
 4 using namespace std;
 5 
 6 int findMagicIndex(vector<int> &v, int start, int end)
 7 {
 8     if (start > end || start > (int)v.size() - 1 || end < 0) {
 9         return -1;
10     }
11     int mid = (start + end) / 2;
12     if (v[mid] == mid) {
13         return mid;
14     }
15     
16     int res = findMagicIndex(v, start, (mid - 1 < v[mid] ? mid - 1 : v[mid]));
17     if (res >= 0) {
18         return res;
19     }
20     res = findMagicIndex(v, (mid + 1 > v[mid] ? mid + 1 : v[mid]), end);
21     return res;
22 }
23 
24 int main()
25 {
26     vector<int> v;
27     int n;
28     int i;
29     
30     while (scanf("%d", &n) == 1 && n > 0) {
31         v.resize(n);
32         for (i = 0; i < n; ++i) {
33             scanf("%d", &v[i]);
34         }
35         printf("%d\n", findMagicIndex(v, 0, n - 1));
36         
37         v.clear();
38     }
39     
40     return 0;
41 }

 

 posted on 2014-03-20 03:08  zhuli19901106  阅读(280)  评论(0编辑  收藏  举报