算法学习day02

160 阅读3分钟

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」。

本文不介绍C++和Java基本语法,想要学习请点击下方链接

菜鸟教程 C++

菜鸟教程 Java

今天正文开始前,首先说明一点,上篇day01末尾的PS中的效率指的是运行时间(速度),算法不仅仅是将程序完整写出,我们还要考虑它的时间复杂度和空间复杂度

基本概念

时间复杂度

计算机科学中,时间复杂性,又称时间复杂度算法时间复杂度是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串长度的函数。时间复杂度常用大O符号表述**

空间复杂度

空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度,记做S(n)=O(f(n))。

一般的递归算法就要有O(n)的空间复杂度了,因为每次递归都要存储返回信息。一个算法的优劣主要从算法的执行时间和所需要占用的存储空间两个方面衡量

例题

1.整数去重

给定含有 n 个整数的序列,要求对这个序列进行去重操作。所谓去重,是指对这个序列中每个重复出现的数,只保留该数第一次出现的位置,删除其余位置。

第一种
#include <cmath>
#include "iostream"
using namespace std;
int main(){
    int n;
    cin>>n;//n是输入值的个数
    int nums[n];
    for(int i=0;i<n;i++){//for循环将输入的n个值赋值入nums数组中
        int num;
        cin>>num;
        nums[i]=num;
    }

    for(int i=0;i<n;i++){
        bool flag= true;//用flag来判断是否重复出现
        for(int j=0;j<i;j++){//遍历之前输入的值,判断是否有重复
            if(nums[i]==nums[j])flag= false;//如果重复将flag赋值为false,之后将不进行输出
        }
        if(flag)//如果是true则输入,否则不输出
            cout<<nums[i]<<" ";
    }
}
第二种
#include <iostream>
using namespace std;
int n;
bool st[110];//将bool类型的数组定义成全局变量,全局变量的bool类型默认赋值为false
int main()
{
	cin >> n;
	for (int i = 0; i < n; i ++ )
	{
		int v;
		cin >> v;//一个for循环直接进行赋值,和遍历输出
		if (st[v]) continue;//检测输入值对应的数组位置值是false还是true
		st[v] = true;//将出现过的值对应的数组位置赋为true,之后再次出现该值会直接执行continue,
        			//这样就避免了再次输出输出过的值
		cout << v << ' ';
	}
	return 0;
} 

PS:continue跳过这一次循环,break是直接退出循环

很显然,第一种方法使用了两层for循环,执行次数是n的平方,而第二种输入、输出、去重直接使用一个循环完成,显然第二种方法要比以一种方法好很多

实测:第一种方法运行时间525ms、而第二种方法运行时常18ms,是一个相当大的差距,当数据异常大的时候这种差距会更明显

2.最长平台

已知一个已经从小到大排序的数组,这个数组中连续的一串值相同的元素就是一个平台,例如,在 1,2,2,3,3,3,4,5,5,6 中 1,2−2,3−3−3,4,5−5,6 都是平台。请输出最长平台的长度。

第一种

#include <cmath>
#include "iostream"
using namespace std;
int main(){
    int n;
    cin>>n;//n是输入值的个数
    int nums[n];
    for(int i=0;i<n;i++){//输入值
        int num;
        cin>>num;
        nums[i]=num;
    }
    int count=1,max=0;//count用来计数,max是用来记录最大的count值
    for(int i=0;i<n;i++){
        if(nums[i]==nums[i+1]){//判断是否和下一个值相等,如果相等count++
            count++;
        }
        else{//如果不相等证明不是一个平台,记录当前的count值,并将count值重置,以免出现错误
            if(count>=max)
                max=count;
            count=1;
        }
    }
    cout<<max;
}

第二种

#include <iostream>
using namespace std;
int n; 
int maxv = 1, cnt = 1;//maxv相当于上一种方法的max,cnt相当于count
int last;//last是用来记录上一个输入的值,用于判断是否相等
int main()
{
	cin >> n;
	cin >> last;
	for (int i = 1; i < n; i ++ )
	{
		int v;
		cin >> v;//直接在输入时直接进行操作
		if (v == last) cnt ++ ;//判断是否与上一个输入值相等,若等进行加法,不然进行重置
		else cnt = 1;
		last = v;//将last值进行更新
		maxv = max(cnt, maxv);//max函数用来比较大小,输出大的值
	}	
	cout << maxv << endl;
	return 0;
}

PS:这两种方法运行效率没有太大差别,都可以使用

输入时直接进行操作是一种思想,这样会简便不少,希望我们之后都可以多使用这种思想