力扣 | 数组和字符串简介

news2024/11/17 3:35:23

在这里插入图片描述

数组是数据结构中的基本模块之一。因为字符串是由字符数组形成的,所以二者是相似的。力扣LeetBook——数组和字符串

文章目录

  • 📚数组简介
    • 👉寻找数组的中心索引
    • 👉搜索插入位置
    • 👉合并区间
  • 📚二维数组简介
    • 👉旋转矩阵
    • 👉零矩阵
    • 👉对角线遍历
  • 📚字符串简介
    • 👉最长公共前缀
    • 👉最长回文子串
    • 👉翻转字典串里的单词
    • 👉实现strStr()

📚数组简介

以下思维套图来源于讨论区——七号7毫升⭐️

来源于讨论区——七号7毫升

在这里插入图片描述

👉寻找数组的中心索引

  • 直接暴力思路,超时了😢

    class Solution 
    {
    public:
        int pivotIndex(vector<int> &nums) 
    	{
            int sum1,sum2;
            for(int i=0;i<nums.size();i++)
            {
            	//中心下标为0的情况
                if(i==0)
                {
                    sum1 = 0;
                    for(int j=1;j<nums.size();j++)
                    {
                        sum2 += nums[j];
                    }
                    if(sum1 == sum2)
                    {
                        return 0;
                    }
                    sum2 = 0;
                }
                //其他
                else
                {
                	//左边的和
                    for(int k=0;k<i;k++)
                    {
                        sum1 += nums[k];
                    }
                    //右边的和
                    for(int j=i+1;j<nums.size();j++)
                    {
                        sum2 += nums[j];
                    }
                    if(sum1==sum2)
                    {
                        return i;
                    }
                    //归零
                    sum1=0;
                    sum2=0;
                }
            }
            return -1;
        }
    };
    

    在这里插入图片描述

  • 改良,考虑左边×2+sum[i]=总和

    class Solution {
    public:
        int pivotIndex(vector<int> &nums) {
            int sum=0;
            for(int i=0;i<nums.size();i++)
            {//先求和
                sum += nums[i];
            }
            int sum1=0;
            for(int i=0;i<nums.size();i++) 
            {
                if(2*sum1+nums[i]==sum) 
                {
                    return i;
                }
                sum1 += nums[i];
            }
            return -1;
        }
    };
    
    

    在这里插入图片描述

👉搜索插入位置

  • 直接暴力循环查找

    class Solution {
    public:
        int searchInsert(vector<int>& nums, int target) {
            for(int i=0;i<nums.size();i++) 
            {
                if(nums[i]>=target) 
                {
                    return i;
                }
            }
            return nums.size();
        }
    };
    

    在这里插入图片描述

  • 改良,因为是升序数组,所以用二分

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

    在这里插入图片描述

👉合并区间

参考官方题解和一位匿名用户的题解——排序

在这里插入图片描述

class Solution {
public:
    //函数名称是 merge,它有一个参数 intervals
    //这个参数是一个引用类型的二维向量 vector<vector​<int>>。
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        if(intervals.size() == 1)
        {//此时不需要合并
            return intervals;
        }
        //先排序,根据Start先排序,确保前一个的Start小于后一个
        sort(intervals.begin(),intervals.end());
        vector<vector<int>> res;
        res.push_back(intervals[0]);//先把第一个压入
        int j = 0;//基数组,以此作为基础合并
        for(int i = j + 1;i < intervals.size();i++)
        {
            //判断,如果第二个子数组的start小于前一个的End,就合并,否则直接压入
            if(intervals[i][0] <= res[j][1])
            {
                //判断前后两个子数组End值大小,取最大的为End
                //因为之前排序过,所以Start是前一个较小,这里不需要再做判断
                res[j][1] = max(res[j][1],intervals[i][1]);
            }
            else
            {
                res.push_back(intervals[i]);
                j++;
            }
        }
        return res;
    }
};

在这里插入图片描述
⭐️sort函数详解

📚二维数组简介

👉旋转矩阵

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n=matrix.size();
        for(int i=0;i<n-1; i++)
        {//先是行列转换
            for(int j=i+1;j<n;j++)
            {
                swap(matrix[i][j], matrix[j][i]);
            }
        }
        for(int i=0; i!=n;i++)
        {//然后镜像翻转
            for(int j=0; j<n/2;j++)
            {
                swap(matrix[i][j], matrix[i][n-j-1]);
            }
        }
    }
};

在这里插入图片描述

👉零矩阵

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int rsize = matrix.size(); //行数
        int csize = matrix[0].size();//列数
        vector<vector<int>> m;//记录值为0的元素的位置
        for(int i=0;i<rsize;i++)
        {//找到0元素所在位置,标记
            for(int j=0;j<csize;j++)
            {
                if(matrix[i][j]==0)
                {
                    m.push_back({i,j});
                }
            }
        }
        for(int i=0; i<m.size(); i++) 
        {//替换
            int j=m[i][0]; //行
            int k=m[i][1]; //列
            for(int i=0;i<csize;i++) 
            {
                matrix[j][i]=0;
            }
            for(int i=0;i<rsize;i++) 
            {
                matrix[i][k]=0;
            }
        }
    }
};

在这里插入图片描述

👉对角线遍历

参考官方题解:直接模拟对角线走向
在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& mat) {
        int m=mat.size();//获取矩阵的行数
        int n=mat[0].size();//获取矩阵的列数
        vector<int> res;//创建一个空向量,用于存储结果
        for (int i=0;i<m+n-1; i++) 
        {//遍历所有可能的对角线索引
            if(i%2) 
            {//奇数索引的对角线
                int x=i<n?0:i-n+1;//计算第一个元素的行索引
                int y=i<n?i:n-1;//计算第一个元素的列索引
                while(x<m && y>=0) 
                {//遍历当前对角线上的所有元素
                    res.emplace_back(mat[x][y]);//将当前元素添加到结果向量中
                    x++;//行索引递增
                    y--;//列索引递减
                }
            } 
            else 
            {//偶数索引的对角线
                int x=i<m?i:m-1;
                int y=i<m?0:i-m+1;
                while(x>=0 && y<n) 
                {
                    res.emplace_back(mat[x][y]);//将当前元素添加到结果向量中
                    x--;//行索引递减
                    y++;//列索引递增
                }
            }
        }
        return res;
    }
};

push_backemplace_back 都是 STL 中 vector 的函数,用于在 vector 的尾部添加元素。但是它们的区别在于添加元素的方式不同。

  • push_back 接受已经构造好的对象作为参数,然后将其加入到 vector 的尾部。

  • emplace_back 接受参数,直接在 vector 的尾部构造对象。

  • 因此 emplace_back 更高效,因为它避免了构造对象的临时副本。

📚字符串简介

👉最长公共前缀

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
        string all;
        all = strs[0]; // all字符串保存第一个字符串
        for (int i = 1; i < strs.size(); i++)
            for (int j = 0; j < all.size(); j++)
                if (all[j] != strs[i][j]) // 比较all字符串和当前字符串的每个字符
                    all.erase(j); // 如果不相等,则删除j及其后面的字符
        return all; // 返回最长公共前缀字符串
    }
};

在这里插入图片描述
⭐️erase函数应用

👉最长回文子串

参考官方题解+动态规划

class Solution {
public:
    string longestPalindrome(string s) {
        int n=s.size();
        if(n<2)
            return s;
        //定义状态数组,dp[i][j]​表示从s字符串中第i个字符到第j个字符的子串是否为回文串。
        //​​vector<vector<bool>> dp​: 这是一个二维向量,每个元素都是一个布尔值。
        //(n, vector<bool>(n, false))​: 这部分表示用 n 作为行数和列数来初始化二维矩阵。每个元素都被初始化为 ​false​。
        vector<vector<bool>> dp(n, vector<bool>(n, false));

        //初始化单个字符的情况
        for(int i=0;i<n; i++)
            dp[i][i]=true;

        int maxLen=1;//记录最长回文子串的长度
        int start=0;//记录最长回文子串的起始位置

        //枚举子串长度
        for(int len=2;len<=n;len++) 
        {
            //枚举子串起始位置
            for(int i=0;i<n-len+1; i++) 
            {
                int j=i+len-1;
                //当子串两端字符相等时
                if(s[i]==s[j]) 
                {
                    //如果子串长度小于等于2,则必定为回文子串
                    //如果子串长度大于2,则根据dp[i+1][j-1]的结果判断是否为回文子串
                    if (len<=2 || dp[i+1][j-1]) 
                    {
                        dp[i][j]=true;
                        if (len>maxLen) 
                        {//更新
                            maxLen=len;
                            start=i;
                        }
                    }
                }
            }
        }
        //返回从​start​位置开始的​maxLen​个字符,提取出最长回文子串。
        return s.substr(start, maxLen);
    }
};

在这里插入图片描述

👉翻转字典串里的单词

  • 首先,定义了两个辅助字符串变量:​word​用于存储当前正在构建的单词,​result​用于存储最终结果。

  • 然后,开始遍历 ​s​字符串。

    • 对于每个字符,如果该字符不是空格,则将其加入到当前正在构建的单词 ​word​中。
    • 当遇到一个空格时,如果前一个字符不是空格,说明一个单词已经构建完成。
    • 此时,将当前构建好的单词添加到结果字符串 ​result​中,并在两个单词之间添加一个空格。
    • 然后清空当前单词 ​word​,准备构建下一个单词。
  • 接下来,处理最后一个单词。如果最后一个单词非空,则将其添加到结果字符串 ​result​中。如果 ​result​为空,则直接将最后一个单词作为结果字符串。

  • 最后,返回结果字符串 ​result​。

class Solution {
public:
    string reverseWords(string s) {
        int n=s.size();
        string word="";  //存储当前正在构建的单词
        string result=""; //存储最终结果

        for(int i=0;i<n;i++) 
        {
            if(s[i]!=' ') 
            {//如果当前字符不是空格,则将其加入到当前正在构建的单词中
                word += s[i];
            } 
            else if(i>0 && s[i-1]!=' ') 
            {//如果当前字符是空格,并且前一个字符不是空格,则说明一个单词已经构建完成
                //将当前构建好的单词添加到结果字符串result中,并在两个单词之间添加一个空格
                result=(result.empty()?word:word+" "+result); 
                word="";//清空当前单词,准备构建下一个单词
            }
        }
        
        //处理最后一个单词
        if (!word.empty()) 
        {
            //如果最后一个单词非空,则将其添加到结果字符串result中
            //如果result为空,则直接将最后一个单词作为结果字符串
            result=(result.empty()?word:word+" "+result);
        }
        return result;
    }
};

在这里插入图片描述


python——使用语言特性

这里是引用

class Solution:
    def reverseWords(self, s: str) -> str:
        return " ".join(reversed(s.split()))

👉实现strStr()

class Solution {
public:
    int strStr(string haystack,string needle) {
        if(needle.empty()) 
        {//如果needle为空字符串,则返回0
            return 0;
        }
        int pos=haystack.find(needle);//在haystack中搜索needle
        //string::npos是一个常量,表示未找到。
        if(pos!=string::npos) 
        {//如果找到了
            return pos;
        }
        return -1; //没有找到,返回-1
    }
};


在这里插入图片描述

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

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

相关文章

adb连接安卓模拟器或真机hook参数加密详细过程(frida)

app逆向时&#xff0c;参数与函数的确定很关键&#xff0c;找到可疑的函数&#xff0c;不确定是否由该函数生成&#xff0c;该怎么解决&#xff1f;hook就应允而生了&#xff0c;首先是要求本地电脑和安卓模拟器&#xff08;网易mumu模拟器支持多系统&#xff0c;该模拟器作为主…

Docker学习笔记23

Docker Swarm架构&#xff1a; Swarm中以集群&#xff08;Cluster&#xff09;为单位进行管理&#xff0c;支持服务层面的操作。 集群是Swarm所管理的对象。 基本概念&#xff1a; 节点&#xff08;Node&#xff09;为Swarm集群中的一个Docker Engine实例。其中管理节点&#…

线程池问题处理

拒绝策略 AbortPolicy&#xff1a;默认的拒绝策略&#xff0c;直接抛出RejectedExecutionException异常。 CallerRunsPolicy&#xff1a;将任务退回给调用者执行。 场景 等线程池里的任务执行完通过future.get的方式获取线程池里的线程执行结果&#xff0c;然后合并到主流程…

自动化平台总结(httprunner+djangorestframework+python3+Mysql+Vue)【基础结构构思】

目录 一、前言 二、简介 三、整体结构 &#x1f381;更多干货 完整版文档下载方式&#xff1a; 一、前言 把一个以前自己搭建的自动化测试平台进行了一下重构升级&#xff0c;记录一下过程中的一些问题和总结。 二、简介 搭建的平台语言使用的是Python3.6&#xff0c;未来…

Oracle中没有show tables;如何用指令来显示表名,Excel关于VLOOKUP函数的使用。

一、问题&#xff1a;Oracle中没有show tables;如何用指令来显示表名。 解决方案&#xff1a; owner NAPSDEV更换为owner CNAPSIIDB。NAPSDEV是用户名&#xff0c;CNAPSIIDB是数据库名。在这里&#xff0c;我想让它显示的是我在Navicat中的CNAPSIIDB数据库下的所有表的名称。所…

Python - Django框架 - 简单运行

pycharm创建django项目 确保安装了Python 安装django pip install Django 创建django项目 django-admin startproject django_study 切换到django目录并启动 cd django_study python manage.py runserver 开发服务器将在默认的localhost:8000上运行&#xff0c;可以在浏览器中访…

vue-cute-timeline插件使用

效果 &#xff08;内容覆盖的有些丑&#xff0c;别在意哈&#xff0c;重点是时间线的展示&#xff09;element也有类似的时间线&#xff0c;但是不能使用类似这样的图片 所以就采用了vue-cute-timeline插件 使用方法&#xff08;可自行百度&#xff09; 安装&#xff1a;npm i…

服务器防止漏洞扫描解决方案

1、定期更新操作系统与应用程序 为了修复可能存在的漏洞和安全问题&#xff0c;建议定期对服务器的操作系统与应用程序进行更新。特别是对于那些常常成为黑客攻击目标的应用程序&#xff0c;比如WordPress等&#xff0c;更新是不可或缺的。通过更新&#xff0c;不仅可以增强服…

管理执行系统-亿发MES智能制造系统赋能制造企业信息化,实现工业现代化

在制造技术领域&#xff0c;质量控制信息集成建设需要健全的管理体系&#xff0c;加强全过程管理。虽然管理执行系统 (MES) 背后的理论思维已经取得了重大进展&#xff0c;但在软件应用集成和分析能力方面仍有改进的空间。本文将探讨MES系统如何赋能制造企业信息化&#xff0c;…

Linux内核源码下载

参考文章&#xff1a;https://blog.csdn.net/m0_49328056/article/details/121669035 一、git命令下载 1、进入官网&#xff1a;https://www.kernel.org/ mainline&#xff08;主线版本&#xff09;、stable&#xff08;稳定版本&#xff09;、longterm&#xff08;长期演进版…

DAY41:贪心算法(十)监控二叉树

文章目录 968.监控二叉树思路遍历顺序空节点处理情况列举 最开始的写法debug测试&#xff1a;travelsal的输出多了1 修改版二叉树注意点时间复杂度总结 968.监控二叉树 给定一个二叉树&#xff0c;我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及…

SpringBoot多模块项目整合JPA,解决被依赖模块Dao层无法注入的问题

DAO层&#xff1a; 报错&#xff1a; 解决办法&#xff1a;被依赖模块的DefaultConfig类加上如下注解&#xff0c;问题即解决 ComponentScan(basePackages "com.fdw.study.*") Configuration EnableJpaRepositories(value "com.fdw.study.dao") EntityS…

Linux0.11内核源码解析-read_write.c

目录 sys_lseek read write read_write.c主要是实现文件系统调用read(),write()和lseek()三个功能 read和write函数分别是调用file_dev.c/pipe.c/block_dev.c/char_dev.c实现相对应的函数 sys_lseek lseek实现系统调用将对文件句柄对应文件结果体中的当前读写指针进行修改&…

matplot 显示文本

import matplotlib.pyplot as plt# 绘制一些数据 x_data [1, 2, 3, 5] y_data [2, 4, 8, 10] plt.plot(x_data, y_data,o,markersize 20)# 添加文本注释 text [a,b,c,d] for i in range(4):plt.text(x_data[i], y_data[i],text[i], fontdict{family: serif, size: 16, col…

leetcode极速复习版-第五章栈与队列

目录 栈与队列 理论基础 232.用栈实现队列 225. 用队列实现栈 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值 239.滑动窗口最大值 347.前 K 个高频元素 栈与队列 理论基础 队列是先进先出&#xff0c;栈是先进后出。 232.用栈实现队列 使用栈实现队…

动态路由,微信小程序绑定

■登录成功之后添加动态路由 ●登录的时候会获取到它的菜单配置■动态路由 | Vue Router <view wx:for"{{list}}">{{index}}--- {{item.name}} </view><view wx:for"{{list}}" wx:for-item "ttt" wx:for-index"num"&…

第二节 给SpringBootAdmin的server端加入spring security安全控制

前言 本来想用一节就写完SpringBootAdmin的&#xff0c;但随着研究的深入发现一节应该是不够的&#xff0c;网上的资料也不会非常系统&#xff0c;官网的例子有些已经好几年没更新了&#xff0c;所以接下来还是系统性的来写下吧 第一节 完成基础配置&#xff0c;暴露所有端点…

Qt-->QQ登陆界面图形化界面

#include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow) {ui->setupUi(this);this->setFixedSize(640,520);//设置窗口标题this->setWindowTitle("QQ&qu…

勒索病毒危害,企业该如何预防勒索病毒

勒索病毒是一种恶意软件&#xff0c;它会对企业内的计算机系统或数据进行加密或锁定&#xff0c;并要求企业支付赎金以解锁或解密。 勒索病毒危害&#xff1a; 数据丢失&#xff1a;勒索病毒可以加密您的文件、照片、视频和其他重要数据&#xff0c;使其无法访问或恢复。如果…

解决centos7和主机win11不能互传文件复制粘贴;及CentOS7最小安装版 VMware Tools安装

linux.iso 中的文件已经加载到 /mnt/cdrom 目录下了。在 /mnt/cdrom 中找到加载出来的文件并拷贝到 /tmp目录下&#xff0c;进行解压。解压好后从中找到 vmware-install.pl&#xff0c;这是vmware tools的安装文件&#xff0c;执行此文件开始安装 ./vmware-install.pl 一路Ente…