【基础算法总结】字符串篇

news2024/11/22 20:12:44

目录

  • 一,算法简介
  • 二,算法原理和代码实现
    • 14.最长公共前缀
    • 5.最长回文子串
    • 67.二进制求和
    • 43.字符串相乘
  • 三,算法总结

一,算法简介

字符串 string 是一种数据结构,它一般和其他的算法结合在一起操作,比如和模拟,高精度加减,双指针,动态规划等算法结合,所以有关字符串类的题型是多种多样的。通过本篇文章挑选的一些题目来熟悉有关字符串接口的使用

二,算法原理和代码实现

14.最长公共前缀

在这里插入图片描述
在这里插入图片描述

算法原理:
这道题的本质是模拟,一般有以下两种模拟方法

解法1:两两字符串比较
可以封装一个函数用来找出两个字符串的最长公共前缀。固定一个字符串,用另一个字符串的每个字符和固定字符串的每个字符进行比较,保存相同的字符,直到其中一个字符串截止或是字符不相等,最后返回保存的字符串即可。
在这里插入图片描述
假设有 n 个字符串,每个字符串的平均长度为 m,则时间复杂度是 O(n*m)

代码实现:

class Solution 
{
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
        // 两两比较
        string ret = strs[0];
        for(int i = 1; i < strs.size(); i++)
            ret = findCommon(ret, strs[i]);

        return ret;
    }

    string findCommon(string& s1, string& s2)
    {
        string tmp = "";
        // 比较两两字符串的每个字符,返回相同的部分。直到一个结束或不相等
        int n = min(s1.size(), s2.size());
        for(int i = 0; i < n; i++)
            if(s1[i] == s2[i]) tmp += s1[i];
            else break;

        return tmp;
    }
};

解法2:统一比较
把每个字符串从头开始每个字符同时比较,保存相同字符(或是保存对应的下标,获取结果时直接截取),直到有一个字符串遍历结束或是字符不相等
在这里插入图片描述
假设有 n 个字符串,每个字符串的平均长度为 m,则时间复杂度也是 O(n*m)。

细节问题:

这里有一个选谁作为参考的问题:
我们可以选第一个字符串作为参考。第一层循环的结束条件用第一个字符串的长度,第二层循环比较字符是否相等时也用第一个字符串的每个字符作参考,如果某一个长度越界了或是字符不相同了就截取

代码实现:

class Solution 
{
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
        // 统一比较
        for(int i = 0; i < strs[0].size(); i++)
        {
            // 以第一个字符串的每个字符为参考
            char tmp = strs[0][i];
            for(int j = 1; j < strs.size(); j++)
            {
                // 某一个长度越界了或是字符不相同
                if(i == strs[j].size() || tmp != strs[j][i])
                    return strs[0].substr(0, i);
            }
        }
        return strs[0];
    }
};

5.最长回文子串

在这里插入图片描述

算法原理:

解法:中心拓展算法
中心拓展算法的本质是使用双指针进行暴力枚举,只不过是根据回文子串的特性枚举的
算法流程:
(1) 遍历字符串,依次固定每一个字符作为中心 i
(2) 从中心点开始,使用双指针 left 和 right,当两者不越界并且两个字符相等时,同时向两边扩展

细节问题:

奇数长度和偶数长度都需要考虑
先定义变量 begin 为回文串的起始长度,len 为回文串的长度
(1) 奇数长度的扩展
定义 left 和 right 作为回文子串边界的下一个位置,left = right = i,若 left 和 right 不越界,且s[left] == s[right],则 left–,right++
当跳出循环,且left 和 right之间的长度 > len 时,就要更新 begin 和 len
(2) 偶数长度的扩展
让 left = i,right = i + 1,其他的与奇数长度的扩展一致

代码实现:

class Solution 
{
public:
    string longestPalindrome(string s) 
    {
        int n = s.size();

        int begin = 0, len = 0;
        for(int i = 0; i < n; i++) // 枚举每个字符为中心
        {
            // 奇数长度拓展
            int left = i, right = i;
            while(left >= 0 && right < n && s[left] == s[right])
                left--, right++;

            // 更新起始位置和长度
            if(right - left - 1 > len)
            {
                begin = left + 1;
                len = right - left - 1;
            }

            // 偶数长度拓展
            left = i, right = i+1;
            while(left >= 0 && right < n && s[left] == s[right])
                left--, right++;

            // 更新起始位置和长度
            if(right - left - 1 > len)
            {
                begin = left + 1;
                len = right - left - 1;
            }
        }

        return s.substr(begin, len);
    }
};

67.二进制求和

在这里插入图片描述

算法原理:

本题是一个二进制的高精度加法模拟题,本质是模拟加法的列竖式运算。
在这里插入图片描述

代码实现:

class Solution 
{
public:
    string addBinary(string a, string b) 
    {
        int i = a.size() - 1, j = b.size() - 1, t = 0;
        string ret = "";
        while(i >= 0 || j >= 0 || t)
        {
            if(i >= 0) t += (a[i--] - '0');
            if(j >= 0) t += (b[j--] - '0');

            ret += (t % 2 + '0');
            t /= 2;
        }

        reverse(ret.begin(), ret.end());
        return ret;
    }
};

43.字符串相乘

在这里插入图片描述
在这里插入图片描述

算法原理:
本题是一道高精度乘法的模拟题

解法1:模拟竖式乘法运算
先把两个字符串逆序,固定一个字符,遍历另一个与它相乘。思路很好想,但是代码不好写,有很多细节
细节问题:
(1) 高位相乘的时候要补"0"
(2) 处理前导0
在这里插入图片描述
(3) 注意最后结果的逆序

解法2:对解法1做优化,先无进位相乘再相加,最后处理进位
这个解法的核心是要借助一个辅助数组。假设两个字符串的长度是m,n,则创建一个大小为 m+n-1的数组,再用两层for循环模拟竖式乘法计算出每一个相乘的值,把每个值都扔进数组中的对应位置,并且把每次相乘的值和原来对应位置的值相加,最后再处理进位

图解1如下

在这里插入图片描述
在这里插入图片描述

图解2如下:
在这里插入图片描述

代码实现:

class Solution 
{
public:
    string multiply(string num1, string num2) 
    {
        // 准备工作
        int n = num1.size(), m = num2.size();
        vector<int> add(n+m-1);
        reverse(num1.begin(), num1.end());
        reverse(num2.begin(), num2.end());

        // 无进位相乘再相加,放入数组的对应位置
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
                add[i+j] += ((num1[i] - '0') * (num2[j] - '0'));
            
        // 处理进位,把数组里的值相加
        int t = 0, i = 0;
        string ret = "";
        while(i < n+m-1 || t)
        {
            if(i < n+m-1) t += add[i++];
            ret += to_string(t % 10);
            t /= 10;
        }

        // 处理前导0
        reverse(ret.begin(), ret.end());
        if(ret[0] == '0') return "0";

        return ret;
    }
};

三,算法总结

字符串类型的算法题型是多种多样的,并且也可以使用多种字符串函数接口了解决问题。

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

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

相关文章

守护数据安全:.rmallox勒索病毒的防范与应对策略

导言 在当今这个数字化时代&#xff0c;网络空间已成为人们生活、工作和娱乐不可或缺的一部分。然而&#xff0c;随着互联网的普及和技术的飞速发展&#xff0c;网络安全问题也日益凸显&#xff0c;成为了一个全球性的挑战。其中&#xff0c;.rmallox勒索病毒作为一种恶意软件…

【linux】进程间的通信(一)

1. 了解进程通信 两个或者多个进程实现数据层面的交互 因为进程独立性的存在&#xff0c;导致进程通信成本较高&#xff08;通信需要成本&#xff09; 2. 进程间通信目的 进程间通信的本质是&#xff0c;让不同的进程看到同一份"资源"&#xff08;即同一份内存空…

基础算法之前缀和--Java实现(下)--LeetCode题解:-和为 K 的子数组 - 和可被 K 整除的子数组 -连续数组-矩阵区域和

这里是Themberfue 和为 K 的子数组 题目解析 返回子数组中所有元素的和等于给定k的个数。 算法讲解 这题好像是用滑动窗口解决&#xff0c;但其实不能&#xff0c;因为 nums 中的元素可能存在负数&#xff0c;就不能保证其单调性的性质。 用前缀和求也不易想到&#xff0c;…

Java编码方式:Base64编码与解码

1、Base64 算法介绍 Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。它主要用于在不支持二进制数据的场合&#xff08;如电子邮件、URL、文件系统名等&#xff09;传输二进制数据。严格来说 Base64 并不是一种加密/解密算法&#xff0c;而是一种编码方式。Bas…

数据挖掘学习笔记:朴素贝叶斯 | Python复现

数据挖掘学习笔记&#xff1a;朴素贝叶斯 机器学习系列&#xff08;四&#xff09;&#xff1a;朴素贝叶斯&#xff08;华强买瓜版&#xff09; - yyxy的文章 - 知乎 十分钟&#xff0c;让你再也忘不掉贝叶斯分类 - VoidHaruhi的文章 - 知乎 《机器学习》&#xff08;西瓜书&am…

快速生成单元测试

1. Squaretest插件 2. 依赖 <dependency><groupId>junit</groupId>

Spring异步线程池的问题

今天看一视频&#xff0c;提到说 Spring默认的异步线程池比较简单&#xff0c;每次执行异步任务&#xff0c;都会新建一个线程进行处理&#xff0c;不会重复利用&#xff0c;所以在用Spring框架开发的时候&#xff0c;需要自定义异步线程池。第一次听到这个说法。遂开始百度。 …

迷你世界表白神器爱心脚本lua

--迷你世界专用爱心表达公式 local a,angle,count,id30,0,0,math.random(668, 681) -- 根据需要调整θ的遍历范围和步长 while true do angle angle0.01 local ra*(math.sin(angle)*(math.sqrt(math.abs(math.cos(angle)))/(math.sin(angle)1.4)-2)2) if r>10…

动手学深度学习59 双向循环神经网络

1. 双向循环神经网络 视频&#xff1a;https://www.bilibili.com/video/BV12X4y1c71W/?p2&spm_id_frompageDriver&vd_sourceeb04c9a33e87ceba9c9a2e5f09752ef8 课件&#xff1a;https://courses.d2l.ai/zh-v2/assets/pdfs/part-3_7.pdf 课本&#xff1a; https://zh-…

机器学习K近邻算法——分类问题K近邻算法示例

针对“数据8.1”&#xff0c;讲解分类问题的K近邻算法&#xff0c;以V1&#xff08;转型情况&#xff09;为响应变量&#xff0c;以V2&#xff08;存款规模&#xff09;、V3&#xff08;EVA&#xff09;、V4&#xff08;中间业务收入&#xff09;、V5&#xff08;员工人数&…

【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则

文章目录 C 继承详解&#xff1a;初阶理解与实战应用前言第一章&#xff1a;继承的基本概念与定义1.1 继承的概念1.2 继承的定义 第二章&#xff1a;继承中的访问权限2.1 基类成员在派生类中的访问权限2.2 基类与派生类对象的赋值转换2.2.1 派生类对象赋值给基类对象2.2.2 基类…

多端同步的收银系统源码

随着经济的不断发展&#xff0c;很多门店越来越趋向连锁品牌化&#xff0c;收银系统自然也成为很多连锁门店必不可少的软件工具。希望通过一套软件可以帮助门店解决门店线下销售、会员管理、连锁多门店管理、线下线上一体化、商品库存管理等难题实现降本增效&#xff0c;为了方…

MySQL连接查询:联合查询

先看我的表结构 emp表 联合查询的关键字&#xff08;union all, union&#xff09; 联合查询 基本语法 select 字段列表 表A union all select 字段列表 表B 例子&#xff1a;将薪资低于5000的员工&#xff0c; 和 年龄大于50 岁的员工全部查询出来 第一种 select * fr…

大模型微调技术之 LoRA:开启高效微调新时代

一、LoRA 简介 LoRA&#xff0c;即低秩适应&#xff08;Low-Rank Adaptation&#xff09;&#xff0c;是一种用于微调大型语言模型的技术&#xff0c;旨在以较小的计算资源和数据量实现模型的快速适应特定任务或领域。 LoRA 方法通过引入低秩近似的思想&#xff0c;对大型预训…

NFS共享文件系统(将文件目录挂载到别的机器上)

我们创建的磁盘是否都必须挂载到本机上&#xff1f;并不是。在 Linux 和其他操作系统中&#xff0c;有一种叫做 NFS&#xff08;网络文件系统&#xff09;的工具&#xff0c;它允许跨网络共享文件系统资源。通过使用 NFS&#xff0c;我们可以将多个客户端服务器的数据目录挂载到…

Java中常见的等待唤醒机制及实践

JDK自带的等待唤醒机制 在Java中&#xff0c;有一个JDK维度的等待唤醒机制。Object类的wait和notify,notifyAll 需要在synchronized同步代码块内并且对象必须获取到锁才能调用。否则会抛IllegalMonitorStateException异常。 当线程在尝试获取锁时失败&#xff0c;会被封装成节…

Mybatis-plus做了什么

Mybatis-plus做了什么 Mybatis回顾以前的方案Mybatis-plus 合集总览&#xff1a;Mybatis框架梳理 聊一下mybatis-plus。你是否有过疑问&#xff0c;Mybatis-plus中BaseMapper方法对应的SQL在哪里&#xff1f;它为啥会被越来越多人接受。在Mybatis已经足够灵活的情况下&…

《强烈推荐一个强大的书签管理工具》

在信息爆炸的时代&#xff0c;我们每天都会浏览大量的网页&#xff0c;收藏各种各样的书签。然而&#xff0c;随着书签数量的增加&#xff0c;管理起来也变得越来越困难。这时&#xff0c;一个强大的书签管理工具就显得尤为重要。今天&#xff0c;我要向大家推荐一款备受好评的…

EtherCAT学习笔记

文章目录 前言一、EtherCAT介绍二、EtherCA系统组成2.1 ESC(EtherCAT从站控制器)2.2 从站控制微处理器2.3 物理层器件2.4 其它应用层器件 三、EtherCAT数据帧结构3.1 寻址方式3.2 时钟3.3 通信模式 四、状态机和通信初始化五、应用层协议六、ESC概述6.1 EtherCAT从站控制芯片6.…

基于SpringBoot+Vue+MySQL的美食信息推荐系统

系统展示 用户前台界面 管理员后台界面 系统背景 在数字化时代&#xff0c;随着人们对美食文化的热爱与追求不断增长&#xff0c;美食信息推荐系统成为了连接食客与美食之间的重要桥梁。面对海量的美食信息&#xff0c;用户往往难以快速找到符合个人口味和需求的美食。因此&…