您的位置:首页 > 其它

《Cracking the Coding Interview》——第9章:递归和动态规划——题目3

2014-03-20 03:08 429 查看
2014-03-20 03:01

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

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

代码:

// 9.3 Given a unique sorted array, find a position where A[i] = i, if one exists.
#include <cstdio>
#include <vector>
using namespace std;

int main()
{
vector<int> v;
int n;
int i;
int ll, rr, mm;

while (scanf("%d", &n) == 1 && n > 0) {
v.resize(n);
for (i = 0; i < n; ++i) {
scanf("%d", &v[i]);
}
if (v[0] > 0 || v[n - 1] < n - 1) {
mm = -1;
} else {
ll = 0;
rr = n - 1;
while (ll <= rr) {
mm = (ll + rr) / 2;
if (v[mm] < mm) {
ll = mm + 1;
} else if (v[mm] > mm) {
rr = mm - 1;
} else {
break;
}
}
if (ll > rr) {
mm = -1;
}
}
printf("%d\n", mm);

v.clear();
}

return 0;
}


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

代码:

// 9.3 Given a sorted array, find a position where A[i] = i, if one exists. The array may have duplicates.
#include <cstdio>
#include <vector>
using namespace std;

int findMagicIndex(vector<int> &v, int start, int end)
{
if (start > end || start > (int)v.size() - 1 || end < 0) {
return -1;
}
int mid = (start + end) / 2;
if (v[mid] == mid) {
return mid;
}

int res = findMagicIndex(v, start, (mid - 1 < v[mid] ? mid - 1 : v[mid]));
if (res >= 0) {
return res;
}
res = findMagicIndex(v, (mid + 1 > v[mid] ? mid + 1 : v[mid]), end);
return res;
}

int main()
{
vector<int> v;
int n;
int i;

while (scanf("%d", &n) == 1 && n > 0) {
v.resize(n);
for (i = 0; i < n; ++i) {
scanf("%d", &v[i]);
}
printf("%d\n", findMagicIndex(v, 0, n - 1));

v.clear();
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐