剑指offer刷题笔记 开端

news2024/11/25 20:44:34

剑指offer刷题笔记

文章目录

    • 剑指offer刷题笔记
      • 注意内容
    • 时间复杂度
    • C++ 语法知识补充:
      • 优先级
      • new 和 delete
      • 树的遍历
    • 算法模板
      • string类判断字符串为空
      • 归并
      • 递归
      • 整数二分算法模板

注意内容

  • map 是 O(logn) ,底层实现是平衡树,unorder_map 是 O(1),哈希表。
  • 树 - 节点, 链表 - 结点
  • (*p).num 改用 p->num 来代替,它表示 *p 所指向的结构体变量中的 num 成员,同样,(*p).name 等价于 p->name
  • 补充:A & B | A & C = A & (B | C)
  • cur是cursor的缩写,译为光标。
  • 深度优先遍历一般是通过递归来实现的,广度优先遍历一般是通过队列来实现的。
  • C++中判断指针是否为空
    • if (root == nullptr) return nullptr;
    • if (!root) return NULL;
  • 下面两种写法等价,因为只有在i = -1 ~i = 0
    • for (int i = n - 1; ~i; i--)
    • for (int i = n - 1; i >= 0; i--)
  • 在用while做指针扫描时,要注意在每个while中进行指针是否越界的判断,因为使用while时往往会越界
    在这里插入图片描述

时间复杂度

  • 计算机1G的空间大约有 109个int,而计算机一秒能运算 107到108次,所以时间复杂度比空间复杂度更重要。

  • 量级

    • C++ 一秒能算 10^7 ~ 10^8 次,一千万次到一亿次
    • 2^20 约等于 100万,即百万个字节约等于1M
    • 2^30 约等于 10亿,即10亿个字节约等于1G
    • log10^x 约等于 3x
  • 时间复杂度排序

    • O(1)<O(lgN)<O(N)<O(N*lgN)<O(n²)<O(n3)<O(2ⁿ)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

C++ 语法知识补充:

  • erase()函数

    erase函数的原型如下:

    (1)string& erase(size_t pos = 0, size_t n = npos);

    (2)interator erase(iterator position);

    (3)iterator erase(iterator first, iterator last);

    有三种用法:

    (1)erase(pos, n); 删除从pos开始的n个字符,例如erase( 0, 1),删除0位置的一个字符,即删除第一个字符。

    (2)erase(position); 删除position处的一个字符(position是个string类型的迭代器)。

    (3)erase(first,last);删除从first到last之间的字符(first和last都是迭代器)。

    int main ()
    {
      string str ("This is an example phrase.");
      string::iterator it;
     
      // 第(1)种用法
      str.erase (10,8);
      cout << str << endl;        // "This is an phrase."
     
      // 第(2)种用法
      it=str.begin()+9;
      str.erase (it);
      cout << str << endl;        // "This is a phrase."
     
      // 第(3)种用法
      str.erase (str.begin()+5, str.end()-7);
      cout << str << endl;        // "This phrase."
      return 0;
    }
    
  • reverse函数用于反转在==[first,last)范围内的顺序(包括first指向的元素,不包括last指向的元素)==

  • push_back()向容器中加入一个右值元素(临时对象)时,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放入容器中。原来的临时变量释放。这样造成的问题就是临时变量申请资源的浪费。

  • emplace_back() 在容器尾部添加一个元素,这个元素原地构造,不需要触发拷贝构造和转移构造。而且调用形式更加简洁,直接根据参数初始化临时对象的成员。

  • stoi() 把数字字符串转换成int输出,参数是const string*,不需要转化为 const char*

  • atoi() 把数字字符串转换成int输出,参数是 const char* ,因此对于一个字符串str我们必须调用 c_str()的方法把这个string转换成 const char*类型的

  • sub_string(string str, int a) 第a个字符开始截取后面所有的字符串

  • resize(n) 设置大小(size)

    • 调整容器的长度大小,使其能容纳n个元素。
    • 如果n小于容器的当前的size,则删除多出来的元素。
    • 否则,添加采用值初始化的元素。
    • 容器调用resize()函数后,所有的空间都已经初始化了,所以可以直接访问。
  • resize(n, t) 多一个参数t,将所有新添加的元素初始化为t

  • reserve() 设置容量(capacity)预分配n个元素的存储空间。

    • reserve()函数预分配出的空间没有被初始化,所以不可访问。
  • auto C++11 auto可以在声明变量的时候根据变量初始值的类型自动为此变量选择匹配的类型。

    • 用auto声明的变量必须初始化(auto是根据后面的值来推测这个变量的类型,如果后面没有值,自然会报错)

    • 函数和模板参数不能被声明为auto(原因同上)

    • 因为auto是一个占位符,并不是一个他自己的类型,因此不能用于类型转换或其他一些操作,如sizeof和typeid。

    • 定义在一个auto序列的变量必须始终推导成同一类型

      • auto x1 = 5, x2 = 5.0, x3='r'; *// This is too much....we cannot combine like this*
    • 示例:

      • std::vector<std::string> ve;
        std::vector<std::string>::iterator it = ve.begin();
        //用atuo来代替那个初始化类型
        auto it = ve.begin();
        
  • int 数据范围

    C中int类型是32位的,范围是-21474836482147483647 
    #define INT_MAX 2147483647
    #define INT_MIN (-INT_MAX - 1)
    

    优先级

在这里插入图片描述

new 和 delete

  1. new

    • new和delete运算符是用于动态分配和撤销内存的运算符,必须成对适用;

    • new用法——开辟单变量地址空间、开辟数组空间;

    • new作用—— 使用new运算符时必须已知数据类型,new运算符会向系统堆区申请足够的存储空间,如果申请成功,就返回该内存块的首地址,如果申请不成功,则返回零值;

    • new出来的对象用对应数据类型的指针接收——**new运算符返回的是一个指向所分配类型变量(对象)的指针。**对所创建的变量或对象,都是通过该指针来间接操作的;

    • new一般使用格式(3种)(开辟单变量地址空间)

      1. 指针类型* 指针变量名 = new 数据类型;
        • int *a = new int 将一个int类型的地址赋值给整型指针a
      2. 指针类型* 指针变量名 = new 数据类型(初值);
        • int *a = new int(2) 作用同上, 但是同时将整数空间赋值为2
      3. 指针类型* 指针变量名 = new 数据类型(内存单元个数);
    • 开辟数组空间

      • 指针类型* 指针变量名 = new 数组类型[数组元素个数];
      • 一维: int *a = new int[100]; //开辟一个大小为100的整型数组空间
      • 二维: int **a = new int[5][6];
  2. delete

    • delete [] 的方括号中不需要填数组元素数,系统自知。即使写了,编译器也忽略。

    • delete用法

      1. 删除单变量地址空间
        • int *a = new int[2];
        • delete a; //释放单个int的空间
      2. 删除数组空间
        • int *a = new int[5];
        • delete []a; //释放int数组空间

树的遍历

DLR–前序遍历–根左右(根在前,从左往右,一棵树的根永远在左子树前面,左子树又永远在右子树前面 )

LDR–中序遍历–左根右(根在中,从左往右,一棵树的左子树永远在根前面,根永远在右子树前面)

LRD–后序遍历–左右根(根在后,从左往右,一棵树的左子树永远在右子树前面,右子树永远在根前面)

  • 前序遍历(根 左 右)

在这里插入图片描述

  • 中序遍历(左 根 右)

在这里插入图片描述

// 打印中序遍历
void dfs(Node* root) {
    if(root == nullptr) return;
    dfs(root->left); // 左
    cout << root->val << endl; // 根
    dfs(root->right); // 右
}
  • 后序遍历(左 右 根)

算法模板

string类判断字符串为空

1、string类有自己的成员函数empty, 可以用来判断是否为空:

string str;
if (str.empty())  //成立则为空

2、判断字符串长度。如果长度为0,则为空:

string str;
if (str.size() == 0)  //成立则为空

3、与空串比较,如果相等则为空:

string str;
if(str == "") //引号里没有空格,成立则为空

几种方法中,empty函数是效率最高也是最常用的一种。

注意:

不能使用str==NULL来判断,NULL一般只拿和指针做比较或者赋给指针,string是类,传参进函数时str调用默认的构造函数已经初始化了,并且str都已经是对象了,它不可能为NULL,也不能和NULL比较。

归并

归并算法核心是分治思想:

  • 分,划分成很多个小的问题,然后递归处理。

  • 治,将分阶段得到的答案整合起来,即为分治思想。

步骤:

  1. 先确定分界点
  2. 然后递归处理(排序)
  3. 最后归并 - 合二为一

归并的每层时间复杂度都是O(n),一共logn层,所以时间复杂度为O(nlogn)

递归

常用递归方法的三种情况:

  • 递归定义的数学函数
  • 具有递归特性的数学结构
  • 可递归求解的问题

在这里插入图片描述

分治法求解递归问题算法的一般形式:

void p(参数表)
{
    if (递归结束条件)
        可直接求解步骤;   //基本项
    else
        p(较小的参数);   //归纳项
}

例如:

long Fact(long n)
{
    if (n == 0)
        return 1;  //基本项
    else
        return n * Fact(n - 1);  //归纳项
}

整数二分算法模板

二分模板一共有两个,分别适用于不同情况。
算法思路:假设目标值在闭区间[l, r]中, 每次将区间长度缩小一半,当l = r时,我们就找到了目标值。

版本1

当我们将区间[l, r]划分成[l, mid][mid + 1, r]时,其更新操作是r = mid(左半边区间)或者l = mid + 1;(右半边区间)计算mid时不需要加1。

C++ 代码模板:

int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    return l;
}

版本2

当我们将区间[l, r]划分成[l, mid - 1][mid, r]时,其更新操作是r = mid - 1(左半边区间)或者l = mid;(右半边区间),此时为了防止死循环,计算mid时需要加1。

C++ 代码模板:

int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1009412.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Thinkphp6 配置并使用redis图文详解 小皮面板

这篇文章主要介绍了Thinkphp6 配置并使用redis的方法,结合实例形式详细分析了Redis的安装、配置以及thinkphp6操作Redis的基本技巧,需要的朋友可以参考下 一、安装redis ThinkPHP内置支持的缓存类型包括file、memcache、wincache、sqlite。ThinkPHP默认使用自带的采用think\Ca…

zabbix监控多实例redis

Zabbix监控多实例Redis 软件名称软件版本Zabbix Server6.0.17Zabbix Agent5.4.1Redis6.2.10 Zabbix客户端配置 编辑自动发现脚本 vim /usr/local/zabbix/scripts/redis_discovery.sh #!/bin/bash #Fucation:redis low-level discovery #Script_name redis_discovery.sh red…

软件外包开发原型图工具

国内有一些原型图管理工具&#xff0c;这些工具旨在帮助团队创建、协作和管理应用程序的原型图。以下是一些国内的原型图管理工具及其特点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.墨刀&…

学习视觉SLAM需要会些什么?

前言 SLAM是现阶段很多研究生的研究方向&#xff0c;我也是作为一个即将步入视觉SLAM的研究生&#xff0c;网上对于SLAM的介绍很多&#xff0c;但很少有人完整系统的告诉你学习视觉SLAM该有那些基础&#xff0c;那么此贴将告诉你学习SLAM你要有那些方面的基础。 文章目录 前言…

在Linux上利用宝塔面板搭建网站,并通过内网穿透方便地实现公网访问

文章目录 前言1. 环境安装2. 安装cpolar内网穿透3. 内网穿透4. 固定http地址5. 配置二级子域名6. 创建一个测试页面 前言 宝塔面板作为简单好用的服务器运维管理面板&#xff0c;它支持Linux/Windows系统&#xff0c;我们可用它来一键配置LAMP/LNMP环境、网站、数据库、FTP等&…

大数据课程M2——ELK的ELASTICSEARCH概述

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解ELK的ELASTICSEARCH概括; ⚪ 掌握ELK的ELASTICSEARCH核心概念; 一、ELASTICSEARCH概括 1. ES安装和启动 注意:如果使用达内云主机,无需安装es,直接配置yml启动即可。 1. 安装 下…

普中51-蜂鸣器实验

蜂鸣器实验 蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。多谐振荡器由晶体管或集成电路构成&#xff0c;当接通电源后&#xff08;1.5~15V 直流工 作电压&#xff09;&#xff0c;多谐振荡…

量化INT8模型报错记录及解决方案

基于C将onnx 模型 转 TensorRT 模型&#xff08;int8&#xff09; 部分命令如下&#xff1a; config->setFlag(nvinfer1::BuilderFlag::kINT8); ICudaEngine* engine builder->buildEngineWithConfig(*network, *config); 出现以下报错&#xff1a; Error Code 4: I…

使用凌鲨进行聚合搜索

作为研发人员&#xff0c;我们经常需要在多个来源之间查找信息&#xff0c;以便进行研发工作。除了常用的搜索引擎如百度和必应之外&#xff0c;我们还需要查阅各种代码文档和依赖包等资源。这些资源通常分散在各个网站和文档库中&#xff0c;需要花费一定的时间和精力才能找到…

闲置的固定资产怎么账务管理

对于那些被遗忘或闲置的固定资产&#xff0c;如何进行有效的账务管理&#xff0c;以实现资产的最大价值&#xff0c;却往往被忽视。本文旨在探讨这一主题&#xff0c;并提供一些创新的策略和实践方法。  需要认识到&#xff0c;闲置的固定资产并非仅仅是财务问题。它们可能代…

【css | loading】各种简单的loading特效

先看一下简单的效果图 线上预览 https://code.juejin.cn/pen/7278511766991339579 代码 HTML <!-- / 1 --><section><div class"sk-rotating-plane"></div></section><!-- / 2 --><section><div class"sk-doub…

OOM分析实战

OOM分析&实战 OOM分析&实战引言&#xff1a;一、JVM内存结构二、JVM OOM错误情况三、实践案例一案例二案例三 四、总结五、分析工具推荐六、参考文献 OOM分析&实战 引言&#xff1a; 在Java开发中&#xff0c;随着应用程序变得越来越复杂&#xff0c;内存管理问题…

运动耳机哪个好、最好的运动牌子排名榜

很多朋友喜欢在运动的时候听音乐&#xff0c;为此&#xff0c;他们会为自己配备一款蓝牙耳机或是运动耳机&#xff0c;可以在运动的时候随身听&#xff0c;可是&#xff0c;一些人在挑选耳机的时候犯难了&#xff0c;市面上那么多运动耳机&#xff0c;运动耳机哪个好&#xff1…

【黄色手套22】6话:构造数据类型

目录 序言&#xff1a; 结构体&#xff1a; 结构体数组&#xff1a; 结构体数组的定义和引用 &#xff1a; 使用关键字typedef自定义类型名&#xff1a; 使用typedef语句为数组类型取别名&#xff1a; 结构体所占内存的大小&#xff1a; 结构体的嵌套&#xff1a; 共用体…

内网穿透——Windows搭建服务器

文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中&#xff0c;观看视频绝对是主力应用场景之一&…

vant 按需导入 vue2

vant 按需导入 vue2 1、通过npm安装 # Vue 3 项目&#xff0c;安装最新版 Vant&#xff1a; npm i vant -S# Vue 2 项目&#xff0c;安装 Vant 2&#xff1a; npm i vantlatest-v2 -S2、自动按需引入组件 babel-plugin-import 是一款 babel 插件&#xff0c;它会在编译过程中…

(Qt+Vs编译环境)报错:引发异常,写入访问权限冲突

起因&#xff1a;在一本Qt的书上看到使用这样的语句 &#xff0c;专门把原有的VS项目模板生成的代码做了修改&#xff0c;如下图所示&#xff1a; UI::MainWindow *ui; ui->setupUI(this); ui->lineEdit->Text(); 然后就开始引发异常&#xff0c;提示访问权限冲突。…

swaggo使用教程

安装与初始化 安装插件 go install github.com/swaggo/swag/cmd/swaglatest 安装依赖 go get -u github.com/swaggo/swag/cmd/swag 在包含main.go文件的项目根目录运行swag init。这将会解析注释并生成需要的文件&#xff08;docs文件夹和docs/docs.go&#xff09;。 swa…

如何快速构建你的AI开放平台?一步步教你!

目录 楔子成品展示后台页面面客端页面成品项目地址 项目源码地址one-apichatgpt-next-web 搭建步骤搭建one-api运行命令命令解释后台配置 搭建chatgpt-next-web运行命令命令解释面客端配置 总结 ✨这里是第七人格的博客✨小七&#xff0c;欢迎您的到来~✨ &#x1f345;系列专栏…

第22章_瑞萨MCU零基础入门系列教程之DMA控制器

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…