剑指offer之数组的调整及在杨氏矩阵中的查找

1.调整数组使奇数全部都位于偶数前面。

题目:输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。

首先分析一下:看到这样一个题目,我们是不是会联想到很多类似的问题,比如说给你一个数组,让你交换使                              其负数在前,正数在后;或者是使一个数的倍数在前,另一个数的倍数在后等等。那么对于此                              题我们是不是可以这样来思考在数组的前半部分找到一个偶数,在后半部分找到一个奇数,然                              后进行交换。

下面我们用代码实现它:

#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;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值