风言枫语  

1.有这样一个数组A,大小为n,相邻元素差的绝对值都是1。如:A={4,5,6,5,6,7,8,9,10,9}。现在,给定A和目标整数t,请找到t在A中的位置。除了依次遍历,还有更好的方法么?(来自新浪微博陈利人)

解法:数组第一个数为array[0], 要找的数为y,设t = abs(y - array[0])。由于每个相邻的数字之差的绝对值为1。故第t个位置之前的数肯定都比y小。因此直接定位到array[t],重新计算tt = abs(y – array[t]),再重复上述步骤即可。这种算法主要利用了当前位置的数与查找数的差来实现跨越式搜索。算法效率要比遍历数组的算法要高一些,并且易于实现。

 

#include <iostream>
#include <cmath>
#include <exception>
using namespace std;

typedef int Index;

int FindNum(int arr[],int len,int target)
{
	if(!arr||len<0)
		throw new runtime_error("Invalid Input");
	Index iter = abs(arr[0]-target);
	while(iter < len){
		if(arr[iter] == target)
			return iter;
		iter += abs(arr[iter] - target);
	}
	return -1;
}

void PrintArray(int arr[],int len)
{
	if(!arr||len<0)
		throw new runtime_error("Invalid Input");
	for(Index iter=0; iter<len; ++iter){
		cout<<arr[iter]<<" ";
	}
	cout<<endl;
}

int main()
{
	const int ARR_MAX = 10;
	int arr[ARR_MAX]={4,5,6,5,6,7,8,9,10,9};

    PrintArray(arr,ARR_MAX);

	int target = 5;
	cout<<target<<"在数组中的索引为:";
	cout<<FindNum(arr,ARR_MAX,target)<<endl;

	target = 11;
	cout<<target<<"在数组中的索引为:";
	cout<<FindNum(arr,ARR_MAX,target)<<endl;

	system("pause");
    return 0;
}


2.一个大小为n的数组,里面的数都属于范围[0, n-1],有不确定的重复元素,找到至少一个重复元素,要求O(1)空间和O(n)时间。

 

#include <iostream>
#include <cmath>
#include <exception>
using namespace std;

typedef int Index;

void Swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

//解法1
// int FindNotReaptedNum(int arr[],int len)
// {
// 	if(!arr||len<0)
// 		throw new runtime_error("Invalid Input");
// 
// 	for(int i=0; i<len; ++i){
// 		while(arr[i] != i){
// 			if(arr[i] == arr[arr[i]])
// 				return arr[i];
// 			Swap(arr[i],arr[arr[i]]);
// 		}
// 	}
// 	
// 	return -1;
// }

//解法2
int FindNotReaptedNum(int arr[],int len)
{
	if(!arr||len<0)
		throw new runtime_error("Invalid Input");

	for(int i=0; i<len; ++i){
		if(arr[i] > 0){
			if(arr[arr[i]]<0)
				return arr[i];
			arr[arr[i]] = -arr[arr[i]];
		}
		else{
			if(arr[-arr[i]]<0)
				return -arr[i];
			arr[-arr[i]] = -arr[-arr[i]];
		}
	}
	
	return -1;
}

void PrintArray(int arr[],int len)
{
	if(!arr||len<0)
		throw new runtime_error("Invalid Input");
	for(Index iter=0; iter<len; ++iter){
		cout<<arr[iter]<<" ";
	}
	cout<<endl;
}

int main()
{
	const int ARR_MAX = 10;
	int arr[ARR_MAX]={2,5,3,5,6,7,8,9,10,1};

    PrintArray(arr,ARR_MAX);

	cout<<"在数组重复的数为:";
	cout<<FindNotReaptedNum(arr,ARR_MAX)<<endl;

	system("pause");
    return 0;
}

本题的解法参考morewindow,详细可以查看原文: google面试题解法1 google面试题解法2
待续。。。。。。。

 


 

posted on 2013-09-03 19:22  风言枫语  阅读(239)  评论(0)    收藏  举报