【代码随想录】鱼与钰遇雨数据结构与算法刷题笔记

代码随想录

https://www.programmercarl.com/

编程素养

代码风格

C++代码风格参考google C++ style Guide
在这里插入图片描述
我使用的是驼峰命名法,其中空格留白的规则如下例:

class Solution {
    
    
public:
    void moveZeroes(vector<int>& nums) {
    
    
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
    
    
            if (nums[fastIndex] != 0) {
    
    
                nums[slowIndex++] = nums[fastIndex];
            }
        }
        for (int i = slowIndex; i < nums.size(); i++) {
    
    
            nums[i] = 0;
        }
    }
};
  1. 操作符左右有空格
  2. 分割符 , ; 后有空格,类似于写英文文章
  3. 控制语句后有空格
  4. 大括号和函数保持在同一行 (Google规范是 大括号和 控制语句保持同一行的)

写算法题目是否用库函数的标准是什么?

如果题目关键的部分直接用库函数就可以解决,建议不要使用库函数。

如果库函数仅仅是 解题过程中的一小部分,并且你已经很清楚这个库函数的内部实现原理的话,那么直接用库函数。

使用库函数最大的忌讳就是不知道这个库函数怎么实现的,也不知道其时间复杂度,上来就用,这样写出来的算法,时间复杂度自己都掌握不好的。

例如for循环里套一个字符串的insert,erase之类的操作,你说时间复杂度是多少呢,很明显是O(n^2)的时间复杂度了。

在刷题的时候本着我说的标准来使用库函数,相信对大家回有所帮助!

算法性能分析

时间复杂度

什么是时间复杂度? 时间复杂度是一个函数,它定性描述某个算法的运行时间。
对于一个算法(或者程序)我们通常会估算它的操作单元数量(例如排序中的比较操作)来代表程序消耗的时间;
假设算法的问题规模为n(即操作的最小数据元素为n。例如排序问题中待排序列长度为n),则得到该问题规模下操作单元数量计算公式f(),那么对于问题规模为n的模型,操作单元数量的计算公式为f(n),其中,随着数据规模n的增大,算法执行时间的增长率和f(n)的增长率相同,这一现象中的增长率称作为算法的渐近时间复杂度,简称时间复杂度,记为 O(f(n))。

其中,O代表上界的,当用它作为算法的最坏情况运行时间的上界,就是对任意数据输入的运行时间的上界。

算法超时问题

首先,算法是否超时喝计算机的配置有关,1GHz=10亿Hz (Hz是赫兹单位)
1Hz 是CPU的一次脉冲(可以理解为一次改变状态,也叫时钟周期),1Hz=1/s,就是一秒1次脉冲,10亿Hz,就是一秒10亿次脉冲。并不是说1次脉冲代表一次计算机的运算,例如对于一个加法运算,cpu要执行四次才能完整这个操作,步骤一:把1放入寄存机,步骤二:把2放入寄存器,步骤三:做加法,步骤四:保存3。 同时存在有多个程序使用CPU的情况。

那我们的计算机究竟1/s能经过多少次运算呢,可以通过代码测试:测试硬件:2015年MacPro,CPU配置:2.7 GHz Dual-Core Intel Core i5 。
1s能进行k++操作 5 × 1 0 8 5\times10^{8} 5×108次。

C/C++基础

#include<iostream>
#define N 10
void sort(int a[], int n);//这里因为代码中方法函数的调用先与定义,因此要声明,反之不用
void print(int a[], int n);
//主函数部分
void main(){
    
    
	int a[N];
	cout<<"input 10 numbers:\n";
	for (int i = 0;i<N; i++)
		cin>>a[i];
	sort(a,N)
	print(a,N);
}
//方法函数定义部分
void sort(int a[], int n){
    
    
	for (int i=0;i<n-1;i++){
    
    
		for(int j=i+1;j<n;j++){
    
    
			if(a[i]<a[j]){
    
    
				int t=a[i];
				a[i]=a[j];
				a[j]=t;
			}
		}
	}
}
//方法函数定义部分
void print(int a[], int n){
    
    
	for (int i=0; i<n; i++)
		cout<<a[i]<<"	";
	cout<<endl;
}

首先,来个整体说明,对于一个C++的程序,需要有三部分

  1. 声明部分
  2. 主函数部分
    也就是Main函数部分
  3. 函数定义部分
    函数定义部分用来定义函数的功能,所有在前面只做了生命的函数都必须在此处进行定义。

其次,我们对代码中的细节进行逐条说明

  1. C++支持c语言中的注释方式/*内容*/;在此基础上增加了行注释符号//,它可以出现在一个行的任何位置,其有效范围是从符号开始到这一行结束。
  2. 每一句程序需要使用;表示其结束
  3. C++中使用cin进行输入数据,cout输出数据,他们的定义在<iostream.h>中,引入这个头文件即可,或者引入c++标准头文件<iostream>效果等价。cin输入数据到内存中的变量中,cout输出数据到屏幕上。
  4. 因为在main()函数中使用sort()和print()函数时,还没定这两个函数的定义,因此需要在开头生命这两个函数,包括1.返回值类型2.函数名3.形式化参数变量
  5. 对于主函数,同C程序一样,C++必须有一个主函数。

例子2

https://leetcode.cn/problems/binary-search/

#include <iostream>
#include <vector>
using namespace std;

class Solution {
    
    
public:
    int minCostClimbingStairs(vector<int>& cost) {
    
    
        vector<int> dp(cost.size());
        dp[0] = cost[0];
        dp[1] = cost[1];
        for (int i = 2; i < cost.size(); i++) {
    
    
            dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];
        }
        return min(dp[cost.size() - 1], dp[cost.size() - 2]);
    }
};

int main() {
    
    
    int a[] = {
    
    1, 100, 1, 1, 1, 100, 1, 1, 100, 1};
    vector<int> cost(a, a + sizeof(a) / sizeof(int));
    Solution solution;
    cout << solution.minCostClimbingStairs(cost) << endl;
}

从代码中可以看出,其实就是定义个main函数,构造个输入用例,然后定义一个solution变量,调用minCostClimbingStairs函数就可以了。

class Person{
    
    
private:
	char name[10];
	char addr[20];
	char phone[11];
public:
	void initData(){
    
    ...};
	char* getAddr(){
    
    ...};
	char* getPhone(){
    
    ...};
}

对于类中的privatepublic区域,其中private区域中的数据定义对外部程序是隐蔽的,public区域中的函数是提供给外部访问类功能的借口。程序中的任何函数只有通过public中的函数才能够修改或者查看类中的private属性。

猜你喜欢

转载自blog.csdn.net/adreammaker/article/details/128407582