编程之美二——数组

        数组是最简单的一种数据结构,它占据一块连续的内存并按照顺序存储数据,由于其内存是连续的于是可以根据下标在O(1)时间内读写,因此其时间效率很高。由于此优点,一般用数组来实现哈希表。为了解决数组空间效率不高的缺点,又设计实现了多种动态数组比如C++的STL中的vector。在C/C++中数组与指针的关系也比较密切。


面试题一:调整数组顺序使奇数位于偶数前面

//调整数组顺序使奇数位于偶数前面
//可以使用两个指针,一个指向头部,它只向后移动,一个指向尾部,它只向前移动
//如果第一个指向的是偶数且第二个指向的是基数则交换指针指向的数字;
//将能被三整除移到不能被三整除的前面或者将负数移到正数前面都一样;
void reorderOddEven(int *array,int length)
{
	if(array==NULL||length<0)
		return;
	int *pBegin=array;
	int *pEnd=array+length-1;
	while(pBegin<pEnd)
	{
		//判断是否为偶数直接与1取与
		while(pBegin<pEnd&&(*pBegin&0x1)!=0)
			pBegin++;
		while(pBegin<pEnd&&(*pEnd&0x1)==0)
			pEnd--;
		if(pBegin<pEnd)
		{
			int temp=*pBegin;
			*pBegin=*pEnd;
			*pEnd=temp;
		}
	}
}


面试题二:数组中出现次数超过一半的数字

enum status{inputVaild,inputInvaild};
int strStatus=inputVaild;
<pre name="code" class="cpp">//数组中出现次数超过一半的数字
//方法一:快速排序取中间数;
//方法二:遍历数组并设置两个变量,一个是数字,一个是次数;
//如果下一个数字和之前保存的数字相同,次数加1,反之减1;
//次数为0时置为1,并保存下一个数字;
//最后一次把次数置为1的数字即为要找的数字;
int findNum(int *array,int length)
{
	//在这里我们假定输入的数组肯定有一个数出现次数超过了一半
	strStatus=inputInvaild;
	if(array==NULL||length<0)
		//设计全局变量标定是否为输入问题
		return 0;
	int rtnNum=array[0];
	int times=1;
	for(int i=1;i<length;i++)
	{
		if(times==0)
		{
			times=1;
			rtnNum=array[i];
		}
		else if(array[i]==rtnNum)
			times++;
		else 
			times--;
	}
	strStatus=inputVaild;
	return rtnNum;
}

 

面试题三:连续子数组的最大和

//连续数组的最大和,O(N)的算法;
//输入一个数组,其中有正数也有负数
//数组中一个或连续多个整数组成一个子数组;
//求所有子数组中和的最大值;
int findMaxSum(int *array,int length)
{
	strStatus=inputInvaild;
	if(array==NULL||length<0)
		return 0;

	int maxSum=array[0];
	int sum=array[0];
	for(int i=1;i<length;i++)
	{
		sum+=array[i];
		if(sum>maxSum)
			maxSum=sum;
		else if(sum<0)
			sum=0;
	}
	strStatus=inputVaild;
	return maxSum;
}

面试题四:和为S的两个正整数

<pre name="code" class="cpp">//输入一个升序数组和一个数字,在数组中查找两个数,使它的和
//正好等于输入的数,要求时间复杂度为O(n),如果有多对则只输入
//任意一对。
bool find(int array[],int length,int sum,int *num1,int *num2)
{
	if(array==NULL||length<1||num1==NULL||num2==NULL)
		return false;
	int high,low;
	high = length -1;
    low = 0;
    while(low<high)
    {
    	if(array[low]+array[high]==sum)
    	{
    		*num1=array[low];
    		*num2=array[high];
    		printf("the two numbers are %d and %d",array[low],array[high]);
    	    return true;
    	}
    	else if(array[low]+array[high]>sum)
    		high--;
    	else if(array[low]+array[high]<sum)
    		low++;
     }
     printf("can not find the two numbers");
     return false;
 }

 

面试题五:和为S的连续正数序列

//输入一个正整数,打印出所有和为S的连续正数序列
void findSquence(int sum)
{
	int small=1,big=2;
	int middle=(1+sum)/2;
	int curSum=small+big;
	while(small<middle)
	{
		if(curSum==sum)
			printNum(small,big);
		while(curSum>sum&&small<middle)
		{
			curSum-=small;
			small++;
			if(curSum==sum)
			printNum(small,big);
	    }
	    big++;
	    curSum+=big;
	}
}
//打印small到big的数字
void printNum(int small,int big)
{
	for(int i=small;i<=big;i++)
		printf("%3d",i);
	printf("\n");
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值