数组

  • 试设计算法在O(n) 时间内将数组A[0…n-1]划分为左右两个部分,使得左边的所有元素为奇数,右边的所有元素均为偶数,要求所使用的辅助存储空间大小为O(1)。
void DivideArr(int A[] , int n){
	int i = 0 , j = n - 1;
	while(i < j){
		while(i < j && A[i] % 2 != 0)
			++i;
		while(j > i && A[j] % 2 == 0)
			--j;
		if(i < j){
			int temp = A[i];
			A[i] = A[j];
			A[j] = temp;
		}
	}
}
  • 判断两个非递减有序的线性表中是否存在相同(关键字值相等)的元素,如果有相同的元素,返回第一个相同元素在第一个有序表中的位置,否则返回0,请选择合适的物理存储结构,用C语言给出该物理存储结构的类型定义,并在其上编写算法。
int A[maxn] , B[maxn]; //用数组的形式存储
int n1 , n2;     //n1记录数组A的长度,n2记录数组B的长度
int FirstElement(int A[] , int n1 , int B[] , int n2){
	int i = 0 , j = 0;
	while(i < n1 && j < n2){
		if(A[i] == B[j])
			return i;
		else if(A[i] > B[j])
			++j;
		else
			++i;
	}
	return 0;
}
  • 在n个元素中,找出第k大的元素,用C语言写出数据结构,设计算法实现上述要求,并分析算法复杂度,最好是平均时间复杂性为O(n)。
int A[maxn] , n;
//基于快排中分区间的思想,从数组A[0..n-1]选择一个枢纽pivot,进行和快排一样的分区间操作,之后数组被
//划分为A[0..m-1] 和 A[m+1...n-1],其中A[m] = pivot.此时有如下三种情况:
//1. m == k , 此时直接返回A[m]即可;
//2. m < k , 则第k大的元素在右区间,因此可对A[m+1..n-1]递归找第k-m大的元素; 
//3. m > k , 则第k大的元素在左区间,因此可对A[0..m-1]递归继续找第k大的元素。
//时间复杂度为O(n)
int partition(int A[] , int L , int R){
	int i = L , j = R;
	int temp = A[L];
	while(i < j){
		while(i < j && A[j] >= temp)  --j;
		if(i < j){
			A[i] = A[j];
			++i;
		}
		while(i < j && A[i] <= temp) ++i;
		if(i < j){
			A[j] = A[i];
			--j;
		}
	}
	A[i] = temp;
	return i;
}

int FindKElement(int A[] , int n , int k){
	int low = 0 , high = n - 1;
	while(low <= high){
		int m = partition(A , low , high);
		if(m == k)
			return A[m];
		else if(m < k){
			low = m + 1;
			k = k - m;
		}
		else
			high = m - 1;
	}
}

  • 输入M个数从中取出N个数进行组合并输出所有组合项。M、N都是不固定的,例如输入M可以是3、5、9、24也可以是8、4、7、21、6、11,N可以是2也可以是5,当然N<M。
//本题意在输出M中N项式组合,用深度搜索即可
void CombineArr(int A[] , int M , int N , int t , int B[] , int visit[]){55
    if(t == N){
        for(int i = 0 ; i < N ; ++i)
            printf("%d%c" , B[i] , " \n"[i == N - 1]);
        return;
    }
    for(int i = 0 ; i < M ; ++i){
        if(visit[i] == 0){
            B[t] = A[i];
            visit[i] = 1;
            CombineArr(A , M , N , t + 1 , B , visit);
            visit[i] = 0;
            B[t] = 0;
        }
    }
}

  • 一个仅由0,1,2三种数构成的数组A共有n个元素,乱序排列在一起,0,1,2的数量大于0,但具体个数未知。请设计一种时间复杂度为O(n)的算法,将数组排成形状00…111…222,(即前面都是0,中间都是1,后面都是2)
//本题是经典的三色旗问题,同样是基于快排分区间的改进
void swap(int A[] , int i , int j){
    int temp = A[i];
    A[i] = A[j];
    A[j] = temp;
}

void partition(int A[] , int n){
    int index = 0;
    int less = -1 , more = n;
    while(index < more){
        if(A[index] == 0)
            swap(A , index++ , ++less);
        else if(A[index] == 1)
            ++index;
        else if(A[index] == 2)
            swap(A , index , --more);
    }
}
  • 给出一系列整数,设计算法求出总和最大的子系列,要求算法的时间复杂性在O(n)之内。比如对于整数系列-1,2,-1,3,-2,总和最大的子系列是2,-1,3。
int getMaxSum(int A[] , int n){
	int maxSum = 0 , sum = 0;
	for(int i = 0 ; i < n ; ++i){
		sum += A[i];
		if(sum < 0)  sum = 0;
		maxSum = maxSum > sum ? maxSum : sum;
	}
	return maxSum;
}
  • 1,2,……,n这n个数,无序地保存在数组c[1…n]中。请编写一个时间复杂度为O(n)的排序算法,将数组c[1…n]按小到大排序。
void Sort(int c[] , int n){
	int x;
	for(int i = 1 ; i <= n ; ++i){      
		while(c[i] != i){
			x = c[i];
			c[i] = c[x];
			c[x] = x;
		}
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值