408数据结构线性表统考真题

线性表

10.2010统考真题

1)

答:循环左移即相当于将前面的p个元素和后面的(n -p) 个元素换一次位置,所以我可以先对整个数组进行一次逆转,再对前面的( (n-p)个元素进行逆转,和后面的p个元素进行逆转。

2)

void Reverse(int* R,int low,int high){
	while(low < high){
		int temp = R[low];
     R[low] = R[high];
     R[high] = temp;
     low++;
     high--;
 }
 return;
}
void Shift(int *R,int p,int n){
 	Reverse(R,0,n-1);
 	Reverse(R,0,n-p-1);
 	Reverse(R,n-p,n-1);
 	return;
}
//用于测试的main函数
int main(){
 	int *r;
 	r = new int[10];
 	for(int i = 0;i < 10;i++){
     	r[i] = i;
 	}
 	for(int i = 0;i < 10;i++){
     	cout << r[i] << " ";
 	}
 	Shift(r,4,10);
 	cout<<endl;
 	for(int i = 0;i < 10;i++){
     	cout << r[i] << " ";
 	}
    return 0;
}

3)
答:时间复杂度是O(n),空间复杂度是O(1)。

11.2011统考真题

1)

答:因为给出的两个数组已经是按照升序进行排列,所以我们不需要再进行排序,直接进行比较。而且两个数组是等长的,所以 L/2 一定是一个整数,所以我们提前计算好中位数所在数组中的序号,然后将两个数组的元素从头到尾比较大小,计数至L/2就是我们所要求的结果。

2)

int FindMidNum(int *A,int *B,int n){
	int i = 0,j = 0;
 int target = n;
 int count = 0;
 int ans = 0;
 while(i < n && j < n){
     if(A[i] <= B[j]){
         ans = A[i];
         i++;
         count++;
     }
     else{
         ans = B[j];
			j++;
         count++;
     }
     if(count == target){
			return ans;
     }
 }
 while(i < n){
		ans = A[i];
     count++;
     i++;
     if(count == target){
			return ans;
     }
 }
 while(j < n){
		ans = B[j];
     count++;
     j++;
     if(count == target){
			return ans;
     }
 }
 return ans;
}
//用于测试的main函数
int main() {
 int* a, * b;
 a = new int[10];
 b = new int[10];
 for (int i = 0; i < 10; i++) {
     a[i] = i + 1;
     b[i] = i + 3;
 }
 for (int i = 0; i < 10; i++) {
     cout << a[i] << " ";
 }
 cout << endl;
 for (int i = 0; i < 10; i++) {
     cout << b[i] << " ";
 }
 cout << endl;
 cout << FindMidNum(a, b, 10);
 return 0;
}

3)

答:时间复杂度O(n),空间复杂度O(1)

12.2013统考真题

1)
答:我们可以采用哈希的思想,因为每一个元素的值是大于等于0小于n的,所以我们可以开辟一个长度为n的辅助数组,b[i]的值表示整数序列A中元素值为i的个数,然后找出数组b[i]中的最大值,若最大值大于n/2,则下标i就是序列A中的主元素,否则返回-1表示没有主元素。

2)

int FindMostNum(int *a,int n){
	int *b = new int[n];
 memset(b,0,sizeof(int) * 10);
 for(int i = 0;i < n;i++){
		b[a[i]]++;
 }
 int max = -1;
 int index = 0;
	for(int i = 0;i < n;i++){
		if(b[i] > max){
			max = b[i];
         index = i;
     }
 }
 if(max > n /2){
		return index;
 }
 else{
		return -1;
 }
}

3)

答:时间复杂度O(n),空间复杂度O(n)

13.2018统考真题

1)

答:数组中一共有n个元素,我们可以设置一个长度为n的辅助数组,我们用a[i]来标识为i+1的正整数有没有在该数组中出现,则会出现两种情况:

  • a[i]的值均为1,那么意味着1-n均在原数组中出现,即未出现的最小正整数为n+1
  • a[i]中有的值为0,下标+1的值就没有在原数组中出现,那么从左到右遍历a数组,第一个值为0的下标+1就是未出现的最小正整数

2)

int FindDisapper(int *r,int n){
    bool *b = new bool[n]();//cpp默认赋值为false
    for(int i = 0;i < n;i++){
		if(r[i] <= n){
			b[r[i] - 1] = true;
        }
    }
    for(int i = 0;i < n;i++){
		if(b[i] == false){
			return i+1;
        }
    }
    return n+1;
}

3)

答:时间复杂度O(n),空间复杂度O(n);

14.2020统考真题

1)

答:

  • a=b=c,那么距离D=0;

  • 无妨设a<b<c,那么由|a-b|表示a到b的距离,|b-c|表示b到c的距离就可以得知|a-b|+|b-c|表示a到c的距离,那么D就是二倍的|a-c|,即二倍的a到c的距离。

所以我们可以设三元组中最小的数为a,最大的数为c,那么D就是2(c-a),又因为三个数组中的元素都是按照升序排列的,所以我们可以从头开始遍历,计算出一个三元组的D之后与之前的进行比较,如果比之前的小则替换之,然后我们找到三元组中最小的那个元素是来自于哪一个数组,然后让他的下标+1,此时a变大,则D减小,当某一个数组遍历结束的时候,此时结束循环,因为如果三元组中的另外两个元素继续增大,会使D的值增大。如果循环期间得到D的值为0,则可以直接退出循环。

2)

//计算绝对值
int MyAbs(int a,int b){
	return a>b?a-b:b-a;
}
//判断是否是最小的数
bool IsMinNum(int a,int b,int c){
	if(a<=b && a<=c) return true;
   else return false;
}
int MinDistance(int *s1,int *s2,int *s3,int n1,int n2,int n3){
	int i = 0,j = 0,k = 0;
   int minDistance = 0x7fffffff;
   while(i<n1 && j<n2 && k<n3 && minDistance>0){
		int temp = MyAbs(s1[i],s2[j])+MyAbs(s2[j],s3[k])+MyAbs(s1[i],s3[k]);
       if(temp < minDistance) minDistance = temp;
       if(IsMinNum(s1[i],s2[j],s3[k])) i++;
       else if(IsMinNum(s2[j],s1[i],s3[k])) j++;
       else k++;
   }
	return minDistance;
}

3)
答:时间复杂度O(n),空间复杂度O(1).

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值