给定一个数组首先增加然后在某一点减少并再次增加? 找到给定数字N是否存在于数组中。
示例1:
Array = 7,8,3,4,5,6
number = 7
答案应该是真的。
示例2:
Array = 3,4,6,7,8,5,9,10,11
number = 10
答案应该是真的。 所有数字都是唯一的。
可以在O(N)
中使用线性搜索完成,
我们能做到这一点吗? (更有效率)
答案 0 :(得分:1)
一般来说,没有。假设我们在Python中有以下内容:
l = range(n)
我们在那里随机贴上-1
:
if random.random() < 0.5:
l[random.randrange(len(l))] = -1
判断列表中是否有-1
的唯一方法是查看每个元素,直到找到它为止。列表的结构最终没有任何帮助。
答案 1 :(得分:0)
线性搜索与非线性数组一样好
答案 2 :(得分:0)
优化算法: -
- 如果找到则使用二进制搜索数组上的键,然后返回true。
- 如果未找到,请使用线性搜索
醇>
时间复杂度: -
搜索失败:在这里我们会进行线性搜索和二进制搜索,因此对于大输入来说是O(N)
成功搜索:这是我们的优化在某种程度上的工作。您最终在二进制搜索中搜索数组右侧部分的概率为1/2。因此平均搜索速度至少快2倍。
优化算法的Java代码及其结果: -
public class UniqueSearch {
static int linearCount = 0;
public static boolean binSearch(int[] arr,int key,int high,int low) {
while(high>=low) {
int mid = (low+high)/2;
if(arr[mid]==key)
return(true);
if(arr[mid]<key) {
low = mid+1;
}
else {
high = mid-1;
}
}
return(false);
}
public static boolean linearSearch(int arr[],int key) {
//System.out.println("linearSearch");
linearCount++;
for(int i=0;i<arr.length;i++) {
if(key==arr[i]) {
return(true);
}
}
return(false);
}
public static boolean optSearch2(int arr[],int key) {
boolean flag = binSearch(arr, key, arr.length-1,0);
if(!flag) {
return(linearSearch(arr, key));
}
return(flag);
}
public static void main(String[] args) {
int n = 100000;
int[] arr = new int[n];
int error = 0;
Random r = new Random();
long start = System.currentTimeMillis();
int totalCount = 0;
for(int i=0;i<1000;i++) {
error = r.nextInt(arr.length-1);
for(int k=0;k<error;k++) {
arr[k] = 2*k+1;
}
for(int k=error;k<arr.length;k++) {
arr[k] = 2*(k-error);
}
for(int j=0;j<1000;j++) {
int x = r.nextInt(arr.length);
totalCount++;
boolean flag = optSearch2(arr,arr[x]);
if(!flag) {
System.out.println("error");
}
}
}
System.out.println("linearSearch Percentage: "+linearCount*100/totalCount);
System.out.println(System.currentTimeMillis()-start);
}
}
结果:
运行代码并等待6-7秒,您将看到随机成功搜索特殊类型的随机数组,因为您的问题需要大约30%的线性搜索,并且可以使用{{{}中的二进制搜索来完成休息1}}
答案 3 :(得分:0)
可以在O(logN)时间复杂度
中完成在数组中查找最大元素(调用此数据透视图)。这是伪代码
public static int getMax(int start, int end){
if(start==end)
return start;
if(start>end)
return -1;
int mid = start + (end-start)/2;
// check if maxima
if(arr[mid-1]<arr[mid] && arr[mid]>arr[mid+1])
return mid;
// check slope
if(arr[mid-1]<arr[mid] && arr[mid]<arr[mid+1]){
//increasing slope
return getMax(mid+1, end);
}
if(arr[mid-1]>arr[mid] && arr[mid]>arr[mid+1]){
return getMax(start, mid-1);
}
return -1;
}
在pivot元素上的分区数组并运行左(增加)和右(减少)的两个二项式搜索
findElem(int key, int pivot){
int index = binSearchInc(start, pivot-1);
if(index>=0)
return index;
else
return binSearchDec(pivot+1, end);
}
这两个步骤都需要O(logN)时间来执行。