数据结构刷题日志

我上学期数据结构与算法拿了85分,15分丢在了算法分析设计上面。(思路,代码,分析各五分)其余全部拿到的情况下,只有对基本算法思路全部非常熟悉,才能拿到满分。所以现在开始每天一道题,为后面算法设计打基础

8.21最大容量
题目描述:
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

示例 1:

输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例 2:

输入:height = [1,1]
输出:1

提示:

n == height.length
2 <= n <= 105
0 <= height[i] <= 104

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/container-with-most-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析:
已知所有的潜在容器壁的高度,使用双指针方法。(我觉得有潜在的贪心算法)开始时,两指针分别指向最左端和最右端,然后将两个指针中较小的那一个向另一侧挪动一位。(这样才有可能找到比当前maxsize更大的容积)

代码实现:

int maxArea(vector<int>& height) {
        int l=0,r=height.size()-1;
        int ans=0;
        while(l<r) {
            int area=(r-l)*min(height[l],height[r]);
            ans=max(ans,area);
            if(height[l]<height[r]) l++;
            else r--;
        }
        return ans;
    }
8.22

【2010统考真题】
算法思想描述:
字符串视为ab,首先将ab分别各自倒置,得a-1b-1,再将a-1b-1整体倒置,得ba
代码:

/*2010年统考真题*/
void reserve(int R[],int from,int to) {//倒置from与to之间的元素 
	int i,temp;
	for(int i=from;i<(to-from+1)/2;i++) 
		swap(R[form+i],R[to-i]); 
}

void converse(int R[],int n,int p){
	reserve(R,0,p-1);
	reserve(R,p,n-1);
	reserve(R,0,n-1);
}

算法分析:(完整版解答)
三个reserve函数的复杂度分别为O(p/2) O((n-p)/2) O(n/2)
时间复杂度O(n)
空间复杂度O(1)

【2011统考真题】
算法设计思想:
由于a,b两序列长度相等,取各自中位数a[m],b[n]进行比较,如果两个中位数相等,则该数为总序列的中位数。如果两中位数不等,则总中位数一定位于现有的两中位数之间。当a[m]>b[n]时,中位数位于a串前半段或b串后半段中,反之亦然。将中位数可能位于的两个半段子串作为新的序列再比较,直到两个中位数相等,即为所求总中位数。
代码描述:
(设计思想有点点问题,我写的是递归实现,由于涉及思想的bug即两中位数不相等,造成无穷递归)下面描述正确的算法思想与代码。

算法设计思想:
分别求A,B的中位数a,b:
若a==b 则a或b为所求中位数
a<b 则舍弃A较小的一半,同时舍弃B较大的一段,并且两次舍弃的长度相等
a>b 则舍弃B较小的一半,同时舍弃A较大的一段
重复以上步骤,直到两个序列中只含一个元素为止
代码描述:(其实我觉得非递归更好,因为没有递归栈,空间复杂度能再低一点)

int M_Search(int a[],int b[],int n) {
	int s1=0,d1=n-1,s2=0,d2=n-1,m1,m2;
	while(s1!=d1||s2!=d2) {
		m1=(s1+d1)/2;
		m2=(s2+d2)/2;
		if(a[m1]==b[m2])
			return a[m1];  //满足条件1
		if(a[m1]<b[m2]) {  //满足条件2 
			if((s1+d1)%2==0) {  //若元素个数为奇数 
				s1=m1;  //舍弃a中间点以前的部分且保留中间点 
				d2=m2;  //舍弃b中间点以后部分且保留中间点 
			} else {
				s1=m1+1;
				d2=m2;
			} 
		} 
		else {
			if((s1+s2)%2==0) {
				d1=m1;
				s2=m2;
			}
			else {
				s1=m1;
				s2=m2+1;
			}
		} 
	}
	return a[s1]<b[s2]?a[s1]:b[s2];
}

8.23
今天看了评分标准,写n2算法可以拿10分,花费大量时间思考最优解是得不偿失的,不应该在这里花费大量时间,于是我打算继续以王道考研书为参考,加快复习步伐,先将所有知识过一遍。先求全面与整体。
【2013统考真题】
标准答案:
算法描述:
从后向前扫描数组元素,标记出一个可能成为主元素的元素num,然后重新计数,确认num是否为主元素。
算法可以分为以下两步:
1.选取候选主元素,依次扫描所给的每个整数,将第一个遇到的整数num保存到c中,记录num的出现次数为1,若遇到下一个整数仍等于num则计数加一,否则计数减一,当计数减到0时,将遇到的下一个整数保存到c中,计数重新记为1,开始新一轮计数,重复以上步骤,直到扫描完全部数组元素。
2.判断c中元素是否是真正的主元素。
再次扫描该数组,统计c中元素出现的次数,若大于等于n/2,则为主元素,否则序列中不存在主元素。
算法实现:(我觉得书上写得有点丑)

int majority(int a[],int n) {
	int i,c,count=1;
	c=a[0];
	for(int i=1;i<n;i++) 
		if(a[i]==c) count++;
		else 
			if(count>0) count--;
			else {
				c=a[i];count=1;
			}
		if(count>0)
			for(i=count=0;i<n;i++)
				if(a[i]==c) count++;
			if(count>n/2) return c;
			else return -1;
		
}

显然,时间复杂度O(n),空间复杂度T(1)

当然,如果不这么做自然也可以。
算法描述:将数组进行排序,依次计算每个数字出现的次数,当该次数大于n/2即为所求的主元素
算法设计:

/*当然要用快排啦*/
void qsort(int a[],int l,int r) {  //有点忘记了 
	if(l>r) return;
	int tmp=a[l];
	int i=l;
	int j=r;
	while(i!=j) {
		while(a[j]>=tmp&&j>i) j--;
		while(a[i]<=tmp&&j>i) i++;
		if(j>i) swap(a[i],a[j]);
	}
	a[l]=a[i];
	a[i]=tmp;
	qsort(a,l,i-1);
	qsort(a,i+1,r);
}

int majority(int a[],int n) {
	qsort(a,0,n-1);//排序 
	int c=1;
	int i=0;
	while(i<n) {
		while(a[i]==a[i+1]) {
		c++; i++;
		}
		if(c>n/2) return a[i-1];
		i++;
		c=1;
	}
	return -1;
}

该算法的时间复杂度O(nlogn)空间复杂度O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
有很多网站可以用来刷考研数据结构题目。其中,一些常见的网站包括leetcode、牛客网和PAT网。这些网站提供了大量的数据结构相关题目,可以帮助考研学生进行练习和提高。 在这些网站上,你可以找到各种类型的数据结构题目,包括链表、树、图、排序等等。你可以根据自己的需要选择适合的题目类型和难度级别来刷题刷题的目的可以有很多,比如为了备考考研的面试、为了参加程序设计竞赛、或者只是为了提高自己的算法能力。不同的目的可能需要选择不同的题目类型和难度级别。因此,在选择题目时,你可以根据自己的目标来进行筛选和练习。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [《数据结构知识点总结》计算机考研复试应届生求职刷题必备.pdf](https://download.csdn.net/download/liuning940307/31275197)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [刷了几千道算法题,这些我私藏的刷题网站都在这里了!](https://blog.csdn.net/u013486414/article/details/102961171)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值