【数据结构】数组和字符串

2023-11-10

本文是对leetbook《数组和字符串》学习完成后的总结。


目标:
理解数组的 基本概念 及其 操作方式;
理解 二维数组 的基本概念,熟悉二维数组的使用;
了解 字符串 的概念以及字符串所具有的不同特性;
理解字符串匹配中的 KMP 算法;
能够运用 双指针 解决实际问题。

数组简介

寻找数组的中心索引

搜索插入位置

合并区间

二维数组简介

旋转矩阵

零矩阵

对角线遍历

字符串简介

最长公共前缀

最长回文子串

翻转字符串里的单词

字符串匹配算法:KMP

实现 strStr()

双指针技巧

双指针情形一:
指针向中间或两端移动,移动方向始终相对

反转字符串

数组拆分 I

两数之和 II - 输入有序数组

双指针情形二:
指针向同侧移动,形成前后指针或快慢指针

移除元素

最大连续1的个数

长度最小的子数组

小结

杨辉三角

杨辉三角是以图的形式展示了二项式的性质
按照性质往下打印即可
一个注意点是先打印两边(第0列和第i列),再打印中间(j<i)

给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。
示例
1: 输入: numRows = 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2:
输入: numRows = 1 输出: [[1]] 提示: 1 <= numRows <= 30

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> ret(numRows);//一共numRows行
        for (int i = 0; i < numRows; ++i) {
            ret[i].resize(i + 1);//第i行有i+1列
            ret[i][0] = ret[i][i] = 1;//每一行的首尾都是1
            for (int j = 1; j < i; ++j) {//除首尾以外的,每个数等于上面两个数之和
                ret[i][j] = ret[i - 1][j] + ret[i - 1][j - 1];
            }
        }
        return ret;
    }
};

杨辉三角Ⅱ

在这里插入图片描述

给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。在「杨辉三角」中,每个数是它左上方和右上方的数的和。
示例 1:
输入: rowIndex = 3
输出: [1,3,3,1]
示例 2:
输入: rowIndex = 0
输出: [1]
示例 3:
输入: rowIndex = 1
输出: [1,1]
提示:0 <= rowIndex <= 33
进阶:你可以优化你的算法到 O(rowIndex) 空间复杂度吗

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> row(rowIndex + 1);//要遍历到rowIndex行所以设置成rowIndex+1的大小
        row[0] = 1;//每行第一个数是1
        for (int i = 1; i <= rowIndex; ++i) {
            row[i] = 1LL * row[i - 1] * (rowIndex - i + 1) / i;//防止数据溢出,要用long long型的
        }
        return row;
    }
};

时间复杂度:O(rowIndex)。
空间复杂度:O(1)。不考虑返回值的空间占用。

反转字符串中的单词Ⅲ

可以再开辟一个数组的空间,也可以原地操作(Java,javascript不适用其string为不可变类型)。
原地操作,向后扫描,遇到空格,调换一个单词的顺序

给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例 1:
输入:s = “Let’s take LeetCode contest” 输出:“s’teL ekat edoCteeL tsetnoc”
示例 2:
输入: s = “God Ding” 输出:“doG gniD”
提示:
1 <= s.length <= 5 * 104
s 包含可打印的 ASCII 字符。
s 不包含任何开头或结尾空格。
s 里 至少有一个词。 s 中的所有单词都用一个空格隔开。

class Solution {
public:
    string reverseWords(string s) {
        int length = s.length();
        int i=0;
        while(i<length){//向后遍历
            int start = i;//记录单词初始位置
            while(i<length&&s[i]!=' '){//遍历到单词结尾
                i++;
            }
            int left = start,right = i-1;//交换一个单词的首尾
            while(left<right){
                swap(s[left],s[right]);
                left++;
                right--;
            }
            while(i<length && s[i]==' '){//遍历下一个单词,空格位置不动
                i++;
            }
        }
        return s;
    }
};

寻找旋转排序数组中的最小值

二分法
对于数组中最后一个数x,在最小值右侧的元素都小于x,在最小值左侧的值都大于x(旋转到前面的一段比后面的一段大),通过这条性质来收缩查找区间。所以只用比较mid和right的大小

已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums =
[0,1,2,4,5,6,7] 在变化后可能得到: 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2] 若旋转 7 次,则可以得到
[0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组[a[n-1], a[0], a[1], a[2], …, a[n-2]] 。
给你一个元素值 互不相同 的数组 nums,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
你必须设计一个时间复杂度为 O(log n)的算法解决此问题。
示例 1: 输入:nums = [3,4,5,1,2] 输出:1 解释:原数组为 [1,2,3,4,5] ,旋转 3次得到输入数组。
示例 2: 输入:nums = [4,5,6,7,0,1,2] 输出:0 解释:原数组为 [0,1,2,4,5,6,7],旋转 4 次得到输入数组。
示例 3: 输入:nums = [11,13,15,17] 输出:11 解释:原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。
提示: n == nums.length 1 <= n <= 5000
-5000 <= nums[i] <= 5000
nums 中的所有整数 互不相同 nums 原来是一个升序排序的数组,并进行了 1 至 n 次旋转。

class Solution {
public:
    int findMin(vector<int>& nums) {
        int left = 0;
        int right = nums.size()-1;
        while(left<right){
                int mid = left+(right-left)/2;
                if(nums[mid]>nums[right]){//找最小值
                    left = mid+1;
                }
                else right = mid;
        }
        return nums[left];
    }
};

删除排序数组中的重复项

双指针。快指针表示遍历数组达到的下标位置,慢指针表示下一个不同的元素要填入的位置。将快指针与其前一个位置所指值比较

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序应该保持 一致 。
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums的前 k 个元素应该保存最终结果。
将最终结果插入 nums 的前 k 个位置后返回 k 。
不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

示例 1
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。 示例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

提示:

1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104 nums 已按 升序 排列

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int fast=1,slow=1;
        if(!nums.size()||nums.size()==1)
        return nums.size();

        for(int i=1;i<nums.size();i++){
            if(nums[fast-1]!=nums[fast]){
                nums[slow++]=nums[fast];
            }
            fast++;
        }
        return slow;
    }
};

移动零

双指针,快指针遍历到达的下标的位置,慢指针指向需要交换的0的位置,快指针碰到非零数就与慢指针的值进行交换

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
进阶:你能尽量减少完成的操作次数吗?

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int n = nums.size();
        int left = 0,right= 0;
        while(right<n){//right向前找非零值
            if(nums[right]){//找到就将其交换,慢指针向后移动一步
                swap(nums[left],nums[right]);
                left++;
            }
            right++;
        }
    }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【数据结构】数组和字符串 的相关文章

  • 静态只读字符串数组

    我在我的 Web 应用程序中使用静态只读字符串数组 基本上数组有错误代码 我将所有类似的错误代码保存在一个数组中并检查该数组 而不是检查不同常量字符串中的每个错误代码 like public static readonly string m
  • CLR 2.0 与 4.0 性能比较?

    如果在 CLR 4 0 下运行 为 CLR 2 0 编译的 NET 程序会运行得更快吗 应用程序配置
  • 以编程方式读取 SQL Server 查询计划建议的 SQL 特定执行的索引?

    如果我在 SSMS 中运行此命令 set showplan xml on GO exec some procedure arg1 arg2 arg3 GO set showplan xml off GO 我获得查询执行中涉及的完整调用堆栈的
  • IdentityServer 4 对它的工作原理感到困惑

    我阅读和观看了很多有关 Identity Server 4 的内容 但我仍然对它有点困惑 因为似乎有很多移动部件 我现在明白这是一个单独的项目 它处理用户身份验证 我仍然不明白的是用户如何注册它 谁存储用户名 密码 我打算进行此设置 Rea
  • 查找进程的完整路径

    我已经编写了 C 控制台应用程序 当我启动应用程序时 不使用cmd 我可以看到它列在任务管理器的进程列表中 现在我需要编写另一个应用程序 在其中我需要查找以前的应用程序是否正在运行 我知道应用程序名称和路径 所以我已将管理对象搜索器查询写入
  • 从客户端访问 DomainService 中的自定义对象

    我正在使用域服务从 Silverlight 客户端的数据库中获取数据 在DomainService1 cs中 我添加了以下内容 EnableClientAccess public class Product public int produ
  • 使用 GCP 的数据存储区时如何区分代码是在模拟器中运行还是在 GKE 中运行

    按照中给出的说明进行操作后 我不确定是否遗漏了任何内容https cloud google com datastore docs tools datastore emulator https cloud google com datasto
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 为什么可以通过ref参数修改readonly字段?

    考虑 class Foo private readonly string value public Foo Bar ref value private void Bar ref string value value hello world
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • 识别 Visual Studio 中的重载运算符 (c++)

    有没有办法使用 Visual Studio 快速直观地识别 C 中的重载运算符 在我看来 C 中的一大问题是不知道您正在使用的运算符是否已重载 Visual Studio 或某些第三方工具中是否有某些功能可以自动突出显示重载运算符或对重载运
  • 为什么我的单选按钮不起作用?

    我正在 Visual C 2005 中开发 MFC 对话框应用程序 我的单选按钮是 m Small m Medium 和 m Large 它们都没有在我的 m Summary 编辑框中显示应有的内容 可能出什么问题了 这是我的代码 Pizz
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex
  • String.Empty 与 "" [重复]

    这个问题在这里已经有答案了 可能的重复 String Empty 和 有什么区别 https stackoverflow com questions 151472 what is the difference between string
  • OpenGL:仅获取模板缓冲区而没有深度缓冲区?

    我想获取一个模板缓冲区 但如果可能的话 不要承受附加深度缓冲区的开销 因为我不会使用它 我发现的大多数资源表明 虽然模板缓冲区是可选的 例如 排除它以利于获得更高的深度缓冲区精度 但我还没有看到任何请求并成功获取仅 8 位模板缓冲区的代码
  • 使用 omp_set_num_threads() 将线程数设置为 2,但 omp_get_num_threads() 返回 1

    我有以下使用 OpenMP 的 C C 代码 int nProcessors omp get max threads if argv 4 NULL printf argv 4 s n argv 4 nProcessors atoi argv
  • GCC 的“-Wl,option”和“-Xlinker option”语法之间有区别吗?

    我一直在查看一些配置文件 并且看到它们都被使用 尽管在不同的体系结构上 如果您在 Linux 机器上使用 GCC 将选项传递给链接器的两种语法之间有区别吗 据我所知 阅读 GCC 手册时 他们的解释几乎相同 From man gcc Xli
  • 如何使用 C++11 using 语法键入定义函数指针?

    我想写这个 typedef void FunctionPtr using using 我该怎么做呢 它具有类似的语法 只不过您从指针中删除了标识符 using FunctionPtr void 这是一个Example http ideone
  • 如何将十六进制字符串转换为无符号长整型?

    我有以下十六进制值 CString str str T FFF000 如何将其转换为unsigned long 您可以使用strtol作用于常规 C 字符串的函数 它使用指定的基数将字符串转换为 long long l strtol str
  • 不区分大小写的字符串比较 C++ [重复]

    这个问题在这里已经有答案了 我知道有一些方法可以进行忽略大小写的比较 其中涉及遍历字符串或一个good one https stackoverflow com questions 11635 case insensitive string

随机推荐

  • YOLOV5学习笔记(一)——原理概述

    目录 一 目标检测概述 1 1 数据集介绍 1 2 性能指标 1 2 1 混淆矩阵 1 2 2 IOU 边界框回归 1 2 3 AP mAP 1 2 4 检测速度 1 3 YOLO发展史 1 3 1 算法思想 1 3 2 YOLOv5网络架
  • NLP学习(九)文本向量化doc2vec及案例实现-Python3实现

    doc2vec基本原理 A distributed memory model 训练句向量的方法和词向量的方法非常类似 训练词向量的核心思想就是说可以根据每个单词的上下文预测 也就是说上下文的单词对是有影响的 那么同理 可以用同样的方法训练d
  • opengl库中gl glu glut glaux的区别

    GL GLU GLUT的关系 OpenGL中的gl库是核心库 glu是实用库 glut是实用工具库 gl是核心 glu是对gl的部分封装 glut是OpenGL的跨平台工具库 gl中包含了最基本的3D函数 而glu似乎对gl的辅助 如果算数
  • AIGC零基础30天学习——CLIP与zero-shot

    在前面对CLIP的学习中 对zero shot prediction环节一直有一些疑惑 zero shot是什么 它该如何进行操作 1 zero shot是什么 zero shot是指零样本学习 和zero shot相关联的概念包括many
  • 用java写一个简单的考勤管理系统

    我可以为您提供一个参考 您可以使用Java语言来编写一个简单的考勤管理系统 具体的步骤如下 1 定义考勤类 它包括考勤日期 考勤时间以及考勤状态 2 定义考勤管理类 实现考勤的添加 删除 查看等操作 3 定义用户类 它包括用户的姓名 职位
  • GO语言网络编程(并发编程)并发介绍,Goroutine

    GO语言网络编程 并发编程 并发介绍 Goroutine 1 并发介绍 进程和线程 A 进程是程序在操作系统中的一次执行过程 系统进行资源分配和调度的一个独立单位 B 线程是进程的一个执行实体 是CPU调度和分派的基本单位 它是比进程更小的
  • 深入源码分析Spring boot 集成Pagehelper

    引入依赖
  • Unity 代码实现多个Image帧动画播放

    using UnityEngine using System Collections using System Collections Generic using UnityEngine UI using System RequireCom
  • 小米9008刷机授权补丁_学会手机刷机这几种方法,这些问题都可以迎刃而解

    智能手机bug很多 尤其是安卓系统的手机 不仅玩游戏卡 运行慢 有时候手机无法正常开机 或者是无法开机 一些功能不能使用 有的是手机系统造成的 只要通过给手机刷机 这些问题都可以迎刃而解 很多人刷机一般都是去手机维修店 但是你看完这篇文章
  • golang中strings.split的使用,分割

    package main import fmt strings func main fmt Printf q n strings Split a b b fmt Printf q n strings Split a boy a girl a
  • 图技术在 LLM 下的应用:知识图谱驱动的大语言模型 Llama Index

    LLM 如火如荼地发展了大半年 各类大模型和相关框架也逐步成型 可被大家应用到业务实际中 在这个过程中 我们可能会遇到一类问题是 现有的哪些数据 如何更好地与 LLM 对接上 像是大家都在用的知识图谱 现在的图谱该如何借助大模型 发挥更大的
  • Jenkins构建(8):Jenkins 执行远程shell :Send files or execute commands over SSH

    Jenkins 执行远程shell Send files or execute commands over SSH 一 远程执行shell命令 python脚本 1 环境配置 管理Jenkins gt Configure System 模块
  • idea 国内插件库_IDEA 超实用使用技巧分享(长篇)

    前言 工欲善其事 必先利其器 最近受部门的邀请 给入职新人统一培训IDEA 发现有很多新人虽然日常开发使用的是IDEA 但是还是很多好用的技巧没有用到 只是用到一些基本的功能 蛮浪费IDEA这个优秀的IDE 同时 在这次分享之后 本人自己也
  • 排序算法——基数排序(C语言)

    基数排序的概念 什么是基数排序 基数排序是一种和快排 归并 希尔等等不一样的排序 它不需要比较和移动就可以完成整型的排序 它是时间复杂度是O K N 空间复杂度是O K M 基数排序的思想 基数排序是一种借助多关键字的思想对单逻辑关键字进行
  • python爬虫从零开始_python爬虫---从零开始(一)初识爬虫

    我们开始来谈谈python的爬虫 1 什么是爬虫 网络爬虫是一种按照一定的规则 自动地抓取万维网信息的程序或者脚本 另外一些不常使用的名字还有蚂蚁 自动索引 模拟程序或者蠕虫 互联网犹如一个大蜘蛛网 我们的爬虫就犹如一个蜘蛛 当在互联网遇到
  • 计算机网络mask是什么意思,mask是什么意思

    你知道mask是什么意思吗 可能你在网络上偶尔会看到这样的词 但网络上的新词多到数不清 根本没有时间去仔细去了解 下面就让我们带你一起 来详细了解一下mask是什么意思吧 mask是什么意思 假面具 伪装 遮蔽物 All guests wo
  • ppt拖动就复制_PPT快捷键丨这些快捷键可助你事半功倍

    工欲善其事 必先利其器 如果你常用的快捷键只有Ctrl C Ctrl V 那你要仔细看下这篇文章了 PS 这个键盘是PPT做的哦 后台回复 键盘 获取源文件 快捷键 顾名思义就是快和方便 所以能熟练使用PPT快捷键 会使我们变得更高效 桔子
  • Shiro和Spring Security对比

    一 Shiro简介 1 什么是Shiro Shiro是apache旗下一个开源框架 它将软件系统的安全认证相关的功能抽取出来 实现用户身份 认证 权限授权 加密 会话管理等功能 组成了一个通用的安全认证框架 2 Shiro 的特点 Shir
  • VMware虚拟机连不上网络,最详细排查解决方案

    虚拟机连不上网 ping某个网站时并显示此信息 ping www baidu com Name or service not known 步骤一 排查Windows自身问题 有可能这个问题不是你虚拟机有问题 而是装虚拟机的Windows本身
  • 【数据结构】数组和字符串

    本文是对leetbook 数组和字符串 学习完成后的总结 数组和字符串 数组简介 寻找数组的中心索引 搜索插入位置 合并区间 二维数组简介 旋转矩阵 零矩阵 对角线遍历 字符串简介 最长公共前缀 最长回文子串 翻转字符串里的单词 实现 st