题目:输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。
首先分析一下:看到这样一个题目,我们是不是会联想到很多类似的问题,比如说给你一个数组,让你交换使 其负数在前,正数在后;或者是使一个数的倍数在前,另一个数的倍数在后等等。那么对于此 题我们是不是可以这样来思考在数组的前半部分找到一个偶数,在后半部分找到一个奇数,然 后进行交换。
下面我们用代码实现它:
#include<stdio.h>
#include<stdlib.h>
void adjust_arr(int arr[],int sz)
{
int tmp=0;
int left=0;
int right=sz-1;
while(left<right)
{
while((left<right)&&(arr[left]%2==1)) //此处再次加上条件left<rigft是为了防止left++后产生溢出现象
{
left++;
}
while((left<right)&&(arr[right]%2==0))
{
right--;
}
if(left<right)
{
tmp=arr[left];
arr[left]=arr[right];
arr[right]=tmp;
}
}
}
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,0};
int i=0;
adjust_arr(arr,10);
for(i=0;i<10;i++)
{
printf("%d",arr[i]);
}
system("pause");
return 0;
}
2.有一个二维数组.数组的每行从左到右是递增的,每列从上到下是递增的(也称之为杨氏矩阵).在这样的数组中查找一个数字是否存在。时间复杂度小于O(N);
首先题目要求要时间复杂度小于O(N),那么我们就应该放弃通过在数组中遍历一遍来找到我们的目标数字的方法。为了提高效率我们该寻求怎样的方法呢?
题目中之所以强调数组的每行从左到右是递增的,每列从上到下是递增的,那么就肯定有它的用意所在,如果我们从数组的右上角或左下角开始找就可以使时间复杂度小于O(N)哦,那是为什么呢?
你想想如果所求数字小于右上角的数字,那么它就小于这一列的数便可排除这一列;如果这个数大于右上角这个数,那么就可以排除这一行转到下一行去找。同理,从左下角开始查找也是这样分析的。这样的话一次查找便可排除一行或一列,是不是效率就提高了很多呀!!!当然也有人会这样思考,我们是不是可以从二维数组的对角线下手呢,这种方法在特殊情况下是可行的,但是如果给你一个数组是三行四列的呢,是不是就不能这样子了啊!
下来我们就用代码实现:
#include<stdio.h>
#include<stdlib.h>
int find_num(int arr[][3],int rows,int cols,int key) //以右上角开始查找
{
int row=0;
int col=cols-1;
while((row<=rows-1)&&(col>=0))
{
if(arr[row][col]==key)
return 1;
else if(arr[row][col]>key)
{
col--;
}
else
{
row++;
}
}
return 0;
}
/*以左下角开始查找
int find_num(int arr[][3],int rows,int cols,int key)
{
int row=rows-1;
int col=0;
while((row>0)&&(col<=cols-1))
{
if(arr[row][col]==key)
return 1;
else if(arr[row][col]>key)
{
row--;
}
else
{
col++;
}
}
return 0;
}*/
int main()
{
int arr[][3]={1,2,3,2,3,4,5,6,7};
int key=0;
int ret=0;
printf("请输入一个要查找的数:\n");
scanf("%d",&key);
ret=find_num(arr,3,3,key);
if(ret==1)
{
printf("查找成功!\n");
}
else
{
printf("查找失败!\n");
}
system("pause");
return 0;
}