返回   cpper编程论坛 > 算法
注册账号 论坛帮助 会员列表 日历事件 搜索 今日新帖 标记版面已读

回复
 
LinkBack 主题工具 显示模式
  #1 (permalink)  
旧 2007-12-06
初级会员
 
注册日期: 2007-12-05
帖子: 2
fxc123 正向着好的方向发展
默认 一道面试题

一个数组,从小到大排序,但是数组是环形的,比如20,24,6,7,9,11,13,哪里是交界不知道,而且元素没重复,请写程序来查找某
个元素是否存在,存在返回其index,否则返回-1。

第一次发贴,大家想想又什么好的方法?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #2 (permalink)  
旧 2007-12-06
bankrock 的头像
高级会员
 
注册日期: 2003-12-11
帖子: 843
文章: 7
bankrock 正向着好的方向发展
默认 回复: 一道面试题

这种情况下一个数组里最多只有一个断点(也就是<关系不成立的那个点)。用二分法查找,平均分割两个数组,一个是“光滑”的(<关系始终成立),另外一个和原数组最多存在一个断点。根据最后一个元素大于第一个元素,判断子数组是否光滑,然后确认要查找的数组是否在这个光滑数组里,不是的话递归查找另外一个子数组。时间复杂度O(lgn)。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #3 (permalink)  
旧 2008-04-14
corelito 的头像
初级会员
 
注册日期: 2008-03-29
帖子: 1
corelito 正向着好的方向发展
默认 回复: 一道面试题

为什么要用二份法呢,直接遍历数组不行?设置两个指针,一前一后进行遍历。。。

此帖于 2008-04-14 02:26 AM 被 corelito 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #4 (permalink)  
旧 2008-04-14
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,135
文章: 20
polyrandom 正向着好的方向发展
默认 回复: 一道面试题

引用:
作者: corelito 查看帖子
为什么要用二份法呢,直接遍历数组不行?设置两个指针,一前一后进行遍历。。。
因为这样做的复杂度是O(n),二分法的复杂度是O(lg n)。如果我们要的只是O(n),那还用两个指针干嘛?一个就行了,直接忽略这个数组的任何排序性质。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #5 (permalink)  
旧 2008-05-31
初级会员
 
注册日期: 2006-02-14
帖子: 7
johnson 正向着好的方向发展
默认 回复: 一道面试题

代码:
#include <stdio.h> #include <assert.h> int recursive_find(int sorted_array[], int start, int end, int value) { if (start > end) { return -1; } if (start == end && value == sorted_array[start]) { return start; } int index = (start + end) / 2; if (value == sorted_array[index]) { return index; } if (value > sorted_array[index]) { return recursive_find(sorted_array, index + 1, end, value); } else { return recursive_find(sorted_array, start, index - 1, value); } } int binary_find(int sorted_array[], int length, int value) { if (0 == sorted_array || length <= 0) { return -1; } return recursive_find(sorted_array, 0, length - 1, value); } int recursive_findex(int circlesorted_array[], int start, int end, int value) { if (start > end) { return -1; } if (value == circlesorted_array[start]) { return start; } if (value == circlesorted_array[end]) { return end; } if (start == end && value == circlesorted_array[start]) { return start; } int head = circlesorted_array[start]; int tail = circlesorted_array[end]; if (head < tail) { return recursive_find(circlesorted_array, start, end, value); } int index = (start + end) / 2; int index_data = circlesorted_array[index]; if (value == index_data) { return index; } if (index_data < tail) { if (value > index_data && value < tail) { return recursive_find(circlesorted_array, index + 1, end, value); } else { return recursive_findex(circlesorted_array, start, index - 1, value); } } else if (index_data > tail) { if (value < index_data && value > head) { return recursive_find(circlesorted_array, start, index - 1, value); } else { // return recursive_find(circlesorted_array, index + 1, end, value); // not recursive_find, should be recursive_findex return recursive_findex(circlesorted_array, index + 1, end, value); } } else { return -1; } } int binary_findex(int circlesorted_array[], int length, int value) { if (0 == circlesorted_array || length <= 0) { return -1; } int head = circlesorted_array[0]; int tail = circlesorted_array[length - 1]; if (head < tail) { return binary_find(circlesorted_array, length, value); } else { return recursive_findex(circlesorted_array, 0, length - 1, value); } } void demo() { int sorted_array[] = {-1, 2, 5, 8, 11, 12, 13, 15, 49, 236, 1231, 9836}; int result = binary_find(sorted_array, sizeof(sorted_array) / sizeof(int), 4); assert(result == -1); printf("the result is: %d\n", result); result = binary_find(sorted_array, sizeof(sorted_array) / sizeof(int), 2); assert(result == 1); printf("the result is: %d\n", result); int circlesorted_array[] = {15, 49, 236, 1231, 9836, -1, 2, 5, 8, 11, 12, 13}; result = binary_findex(circlesorted_array, sizeof(circlesorted_array) / sizeof(int), 4); assert(result == -1); printf("the result is: %d\n", result); result = binary_findex(circlesorted_array, sizeof(circlesorted_array) / sizeof(int), 8); assert(result == 8); printf("the result is: %d\n", result); }

此帖于 2008-05-31 04:34 AM 被 johnson 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #6 (permalink)  
旧 2008-06-01
liuxinyu 的头像
高级会员
 
注册日期: 2006-02-09
帖子: 303
文章: 48
liuxinyu 正向着好的方向发展
默认 回复: 一道面试题

感觉程序不会这么长,略微整理了一下。一共两大类情况:
假设待查找序列为x[i+1],...,x[n],x[1],...,x[i]序列长度为n,待查数值为v

情况1,二分点j落在i+1和n之间
这种情况下x[i+1]<x[j]且x[j]>x[i]
若v==x[j],返回;
若v>x[j],在右侧子序列查找,反之则既要在左侧子序列查找,也要在右侧子序列查找;

情况2,二分点j落在1和i之间
这种情况下x[i+1]>x[j]且x[j]<x[i]
若v==x[j],返回;
若v<x[j],在左侧子序列查找;反之则既要在左侧查找也要在右侧查找。

代码如下:
代码:
#include <vector> #include <iostream> #include <algorithm> template<typename T> int b_find(T& xs, int v){ if(xs.empty()) return -1000; if(xs.size()==1) return xs[0]==v? 0: -1000; int offset=xs.size()/2; if(v==xs[offset]) return offset; T left(xs.begin(), xs.begin()+offset); T right(xs.begin()+offset, xs.end()); int i; if(xs.front()<xs[offset] && xs[offset]>xs.back()) if(v>xs[offset]) return b_find(left,v); else if((i=b_find(left, v))>0) return i; else return left.size()+b_find(right,v); else //xs.front()>xs[offset] && xs[offset]<xs.back() if(v<xs[offset]) return b_find(left, v); else if((i=b_find(right, v))>0) return i+left.size(); else return b_find(left,v); } template<typename T> int binary_find(T& xs, int v){ int res=b_find(xs, v); return res<0? -1: res; } int main(int, char**){ const int xs[]={20, 24, 6, 7, 9, 11, 13}; std::vector<int> xsv(xs, xs+sizeof(xs)/sizeof(int)); std::cout<<binary_find(xsv, 6)<<"\n"; std::cout<<binary_find(xsv, 15)<<"\n"; }
运行结果如下:
chen@chen-PC /cygdrive/d/liuxinyu/temp/c++
$ g++ foo1.cpp

chen@chen-PC /cygdrive/d/liuxinyu/temp/c++
$ ./a
2
-1

此帖于 2008-06-01 09:10 PM 被 liuxinyu 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
回复

书签

主题工具
显示模式

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛启用 表情符号
论坛启用 [IMG] 代码
论坛禁用 HTML 代码
Trackbacks are 启用
Pingbacks are 启用
Refbacks are 启用



所有时间均为格林尼治时间 +9。现在的时间是 09:30 AM


Powered by vBulletin® 版本 3.7.0
版权所有 ©2000 - 2008,Jelsoft Enterprises Ltd.
(C) Copy Right All Right Reserved 2001 - 2007

Search Engine Friendly URLs by vBSEO 3.1.0