1.把一个数组最开始的若干个元素搬到素组的末尾,我们称之为数组的旋转。输入一个递增的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2} 为{1,2,3,4,5}的一个旋转,找出该数组中的最小数也就是1。
分析:首先肯定会想到直接一个一个进行比较不是就可以了吗,但是细心的人会注意到这个题目中特别突出的就是一个递增的词语,这说明这个数组一开始是有序的,尽管进行了旋转也就是有点循环移位的意思,但是大部分肯定还是有序的,再经过分析,是最多两部分基本有序,有时候还是直接就是原数组有序,这就让我们这个猿猴们想到了用二分查找的方法,从基本的O(n)---------->O(logn)
下图是{4,5,1,2,3} 进行查找的一个步骤图:
具体的实现代码如下:
int find_min_from_array(int array[],int length)
{
if(array == 0 || length <=0)
{
return -1;
}
int left = 0;
int right = length-1;
int mid = left;
while(array[left] >= array[right])
{
if(right - left == 1)
{
mid = right;
break;
}
mid = left +((right-left)>>1);
if(array[mid] == array[left] && array[mid] == array[right])
{
mid =0;
for(int i=1;i<length;++i)
{
if(array[i] < array[mid])
{
mid = i;
}
}
break;
}
if(array[mid] >= array[right])
{
left = mid;
}
else if(array[mid] <= array[right])
{
right = mid;
}
}
return mid;
}
int main()
{
//int array[]={4,5,1,2,3};
int array[]={1,0,1,1,1}; //当出现这种最左边和最右边还有中间数据相等的情况,这个时候只能进行正常的查找
cout<<find_min_from_array(array,5)<<endl;
return 0;
}
2.求斐波那契数的第N项的值
底下是递归和非递归的实现:
//递归实现
int Recur_Fibonacci(int n)
{
if(n<0)
{
return -1;
}
if(n==0 || n== 1)
{
return n;
}
return (Recur_Fibonacci(n-1)+Recur_Fibonacci(n-2));
}
//非递归实现
int Loop_Fibonacci(int n)
{
if(n<0)
{
return -1 ;
}
if(n==0 || n== 1)
{
return n;
}
int f1=0;
int f2=1;
int f3=0;
while(n>=2)
{
f3=f1+f2;
f1=f2;
f2=f3;
--n;
}
return f3;
}
int main()
{
cout<<Loop_Fibonacci(6)<<endl;
return 0;
}
3.求二进制中1的个数首先我们会想到直接从数据的最左边开始进行&1就可以取出第一个位的数据 ,再进行计算,所以就出现了底下的代码
int Number_Of_One(int n)
{
int count=0;
while(n)
{
if(n & 1)
{
count++;
}
n>>=1;//但是这种出现负数的时候移位就会引起数据的变化,因为负数是左移高位补符号
}
return count;
}
就如上边说的如果是负数会出现问题
所以我们要想到另一种做法
int Number_Of_One(int n)
{
int count = 0;
while(n) //当n的所有位全部变成0的时候结束
{
count++;
n &= (n-1); //n-1的使得最后一个位1变成了0
}
return count;
}
//扩展:求零的个数
int Number_Of_Zero(int n)
{
int count=0;
while(n+1)//当n的所有位全变成1的时候再加一就是0了
{
count++;
n |= (n+1);//n+1将n的最后一个位0变成了1
}
return count;
}
int main()
{
cout<<Number_Of_One(15)<<endl;
cout<<Number_Of_Zero(15)<<endl;
return 0;
}
4.
//求数值的整数次方
double Power(double num,int n )
{
if((num>-0.0000001 && num < 0.0000001))
{
return 0.0;
}
if(n == 0)
{
return 1.0;
}
if(n < 0)
{
n=-n;
}
double result=1.0;
while(n)
{
result *= num;
--n;
}
if(n < 0)
{
result=1.0/result;
}
return result;
}
int main()
{
cout<<Power(0,1)<<endl;
return 0;
}
5.打印 1到-----N个数字组成的最大数
bool Increment(char *number,int n)
{
bool ret = false;
int ntakeover = 0;
for(int i=n-1;i>=0;--i)
{
int sum = number[i]-'0'+ntakeover;
if(i == n-1) //个位数字加一
{
sum++;
}
if(sum==10) //个位加1之后等于10的时候。这样加一上来只能等于10
{
if(i==0) //如果此时最高位加一位10 的时候那就是最大数的时候,此时终止
{
ret = true;
}
else
{
sum -= 10;
ntakeover=1; //进一位
number[i]='0'+sum; //个位赋值
}
}
else //个位加一之后没有10大的
{
number[i]='0'+sum;
break;
}
}
return ret;
}
void PrintNumber(char *number,int n)
{
bool begin=true; //begin用于控制输出类似于10 20 后边的零
for(int i=0;i<n;++i)
{
if(begin && number[i] != '0')
{
begin=false;
}
if(!begin)
{
cout<<number[i];
}
}
}
void Print1ToMaxOfNdigit(int n)
{
if(n <=0 )
{
return ;
}
char *number= new char[n+1];
memset(number,'0',n);
number[n]='\0';
while(!Increment(number,n)) //每次循环进去执行
{
PrintNumber(number,n);
cout<<" ";
}
cout<<endl;
delete []number;
}
int main()
{
Print1ToMaxOfNdigit(2);
return 0;
}