C++ 字符串OJ

目录

1、14. 最长公共前缀

2、 5. 最长回文子串

3、 67. 二进制求和

4、43. 字符串相乘


1、14. 最长公共前缀

 思路一:两两字符串进行比较,每次比较过程相同,可以添加一个函数辅助比较,查找最长公共前缀。

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        string ret = strs[0];
        for (int i = 0; i < strs.size(); i++) {
            ret = findcommon(ret, strs[i]);
        }
        return ret;
    }
    string findcommon(string& s1, string& s2) {
        int i = 0;
        while (i < min(s1.size(), s2.size()) && s1[i] == s2[i]) {
            i++;
        }
        return s1.substr(0, i);
    }
};

思路二:选取一个字符串与其他字符串逐位比较,比较过程中如果有一个字符串能遍历到最后或某个字符与当前比较的字符不相等,则该字符串为最长公共前缀。

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        for (int i = 0; i < strs[0].size(); i++) {
            char s = strs[0][i];
            for (int j = 1; j < strs.size(); j++) {
                if (i == strs[j].size() || s != strs[j][i])
                    return strs[0].substr(0, i);
            }
        }
        return strs[0];
    }
};

2、 5. 最长回文子串

 

 思路:中心扩展法

  • 中心扩展法:这种方法的核心思想是,回文子串的构造是对称的,所以可以从中心开始向两边扩展,检查两边的字符是否相等。这种方法需要考虑奇数长度和偶数长度的回文子串,因此对每个字符尝试两次扩展:一次将其视为中心(奇数长度),一次将其和下一个字符共同视为中心(偶数长度)。

  • 时间复杂度:由于需要对字符串中的每个字符都尝试向两边扩展,最坏情况下每次扩展可能会遍历整个字符串,因此总的时间复杂度为O(n^2),其中n是字符串的长度。

  • 空间复杂度:这个算法只使用了固定的额外空间(beginlen等变量),因此空间复杂度为O(1)。

通过这种方法,即使在字符串长度较长的情况下,也能有效地找到最长的回文子串。

class Solution {
public:
    string longestPalindrome(string s) {
        int begin = 0, len = 0, n = s.size();
        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);
    }
};
  1. 首先,定义了三个变量:begin(记录最长回文子串的起始位置)、len(记录最长回文子串的长度)、n(记录字符串s的长度)。

  2. 然后,通过一个循环遍历字符串s中的每个字符。在循环中,以当前字符为中心,向两边扩展,找到以当前字符为中心的最长回文子串长度。

  3. 在第一个循环中,以当前字符为中心,向左右两边扩展,直到不再满足回文条件(即字符不相等或越界)。在扩展的过程中,记录下当前回文子串的起始位置和长度。

  4. 接着,在第二个循环中,以当前字符和下一个字符为中心,向左右两边扩展,找到以这两个字符为中心的最长回文子串长度。

  5. 在每次扩展过程中,比较当前找到的回文子串长度与之前记录的最长回文子串长度,如果当前找到的更长,则更新beginlen

  6. 最后,返回找到的最长回文子串,通过使用substr函数从原始字符串s中截取出最长回文子串。

3、 67. 二进制求和

 思路:模拟列竖式计算,注意二进制求和逢二进一。

class Solution {
public:
    string addBinary(string a, string b) {
        int cur1 = a.size() - 1, cur2 = b.size() - 1;
        string ret;
        int t = 0;
        while (cur1 >= 0 || cur2 >= 0 || t) {
            if (cur1 >= 0)
                t += a[cur1--] - '0';
            if (cur2 >= 0)
                t += b[cur2--] - '0';
            ret += t % 2 + '0';
            t /= 2;
        }
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

4、43. 字符串相乘

 思路一:无进位相加,这个算法的关键在于通过逐位相乘和处理进位来实现大数乘法,避免了直接使用大数运算,使得算法能够处理非常大的数。

class Solution {
public:
    string multiply(string num1, string num2) {
        reverse(num1.begin(), num1.end());
        reverse(num2.begin(), num2.end());
        int m = num1.size(), n = num2.size();
        vector<int> tmp(m + n - 1);
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                tmp[i + j] += (num1[i] - '0') * (num2[j] - '0');
            }
        }
        int cur = 0, t = 0;
        string ret;
        while (cur < m + n - 1 || t) {
            if (cur < m + n - 1) {
                t += tmp[cur++];
            }
            ret += t % 10 + '0';
            t /= 10;
        }
        while (ret.size() > 1 && ret.back() == '0') {
            ret.pop_back();
        }
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

 整个过程模拟了人工进行乘法计算的过程,先计算每一位的乘积然后逐步处理进位,最后得到结果。这种方法不依赖于任何大数处理库,能够处理非常大的数的乘法,只受限于内存和处理时间。

  1. 反转字符串:首先,将num1num2两个字符串反转,这样做是为了从最低位开始计算乘积,便于后续的逐位相乘和累加。

  2. 初始化临时数组:创建一个长度为m + n - 1的临时数组tmp,用于存储乘积的每一位。这里mn分别是num1num2的长度。数组的长度之所以是m + n - 1,是因为两个数最多可以产生这么长的乘积。

  3. 逐位相乘:遍历num1num2的每一位,将每一位的乘积累加到tmp数组对应的位置上。这里使用(num1[i] - '0') * (num2[j] - '0')来计算两位数字的乘积,并累加到tmp[i + j]上。

  4. 处理进位:遍历tmp数组,将每一位的值加上前一位的进位t,然后计算当前位的值(t % 10)和新的进位(t / 10)。这一步确保了每一位上的数字都是单个数字,并且正确处理了进位。

  5. 去除前导零:由于最开始反转了字符串,最终得到的结果也是反转的,且可能包含前导零。因此,需要去除结果字符串尾部的所有'0',直到结果字符串的长度大于1或者最后一个字符不是'0'。

  6. 反转结果字符串:最后,将结果字符串再次反转,得到正确的乘积结果。

  7. 返回结果:返回处理后的结果字符串。

思路二: 直接模拟

class Solution {
public:
    string multiply(string num1, string num2) {
        if (num1 == "0" || num2 == "0")
            return "0";
        int n1 = num1.size(), n2 = num2.size();
        string result(n1 + n2, '0');
        for (int i = n1 - 1; i >= 0; i--) {
            for (int j = n2 - 1; j >= 0; j--) {
                int product = (num1[i] - '0') * (num2[j] - '0') +
                              (result[i + j + 1] - '0');
                result[i + j + 1] = product % 10 + '0';
                result[i + j] += product / 10;
            }
        }

        size_t startpos = result.find_first_not_of("0");
        return result.substr(startpos);
    }
};
  1. 特殊情况处理:如果num1num2中任何一个是"0",则乘积也是"0",直接返回"0"。

  2. 初始化结果字符串:创建一个长度为n1 + n2的字符串result,所有位初始化为'0'。这是因为两个长度分别为n1n2的数相乘,其结果长度最多为n1 + n2

  3. 逐位相乘并累加:从num1num2的最低位开始(即字符串的末尾),对每一对位进行乘法运算,并将乘积累加到结果字符串的相应位置。这里需要注意的是,乘积需要加上结果字符串中已经存在的数值(因为可能之前已经有累加的结果),所以使用(result[i + j + 1] - '0')来获取并更新结果。

  4. 处理进位:计算每一步的乘积后,可能会产生进位。进位被加到下一位的累加结果中。这里通过result[i + j + 1] = product % 10 + '0';来更新当前位的结果,并通过result[i + j] += product / 10;来处理进位。

  5. 去除前导零:由于初始化结果字符串时所有位都是'0',乘积的计算可能会在结果字符串的前面留下一些不必要的零。使用find_first_not_of("0")找到第一个非零字符的位置,并使用substr方法截取从这个位置到字符串末尾的子串作为最终结果。

  6. 返回结果:如果结果字符串中没有找到非零字符(即find_first_not_of返回string::npos),则说明结果为0;否则,返回去除前导零后的结果字符串。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue.set:Vue中的数据绑定利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【JAVA/Web】数组转对象

一. 需求 数组转对象 数组结构 List:[{id:1,code:phone,value:10101001},{id:2,code:name,value:admin},{id:3,code:address,value:XXXXXX} ]二. 数组转对象&#xff08;键值对映射关系&#xff09; 对象结构 object:{phone:10101001,name:admin,address:XXXXXX }2.1 Java…

Java Socket:飞鸽传书的网络套接字

套接字&#xff08;Socket&#xff09;是一个抽象层&#xff0c;应用程序可以通过它发送或接收数据&#xff1b;就像操作文件那样可以打开、读写和关闭。套接字允许应用程序将 I/O 应用于网络中&#xff0c;并与其他应用程序进行通信。网络套接字是 IP 地址与端口的组合。 01、…

VUE3 使用axios网络请求

1.新建工程 参考&#xff0c;VUE3 环境搭建&#xff1a;https://blog.csdn.net/LQ_001/article/details/136293795&#xff0c;运行命令 vue create vue-demo 2.引入axios 不管何种引用&#xff0c;都要在工程中安装 axios 包。安装命令&#xff1a;npm install --save axio…

linux paddle For C++环境搭建

paddle介绍 Paddle是类似tesseract的文字识别ocr。因为tesseract-ocr的中文识别效果不好。因此才准备安装Paddle。Paddle最方便的安装方式的使用Python的包管理安装。pip3 install paddlepaddle。但我使用了一下感觉还是用C更加方便&#xff0c;QT OpenCV Paddle应当还不错。…

Go语言必知必会100问题-19 浮点数溢出问题

问题呈现 在Go语言中&#xff0c;有两种浮点数类型&#xff08;虚数除外&#xff09;&#xff1a;float32和float64. 浮点数是用来解决整数不能表示小数的问题。我们需要知道浮点数算术运算是实数算术运算的近似&#xff0c;下面通过例子说明浮点数运算采用近似值的影响以及如…

⭐每天一道leetcode:83.删除排序链表中的重复元素(简单;链表遍历、删除经典题目)

⭐今日份题目 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 示例1 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2] 示例2 输入&#xff1a;head [1,1,2,3,3] 输出&#xff1a;[1,2,3] …

【R语言爬虫实战】抓取省市级城市常务会议内容

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

enumerate函数的用法

enumerate() 函数是 Python 内置函数之一&#xff0c;用于同时返回可迭代对象的索引和对应的值。 它的语法结构如下&#xff1a; enumerate(iterable, start0) iterable: 表示一个可迭代的对象&#xff0c;如列表、元组、字符串等。start: 可选参数&#xff0c;表示索引起始…

02hadoop伪分布式搭建

3. 环境安装 3.1 安装方式 单机模式 只能启动MapReduce 伪分布式 能启动HDFS、MapReduce 和 YARN的大部分功能 完全分布式 能启动Hadoop的所有功能 3.2 安装JDK 3.2.1 JDK安装步骤 下载JDK安装包&#xff08;下载Linux系统的 .tar.gz 的安装包&#xff09; https://www…

网络协议常见问题

网络协议常见问题 OSI&#xff08;Open Systems Interconnection&#xff09;模型OSI 封装 TCP/IP协议栈IP数据报的报头TCP头格式UDP头格式TCP (3-way shake)三次握手建立连接&#xff1a;为什么三次握手才可以初始化 Socket、序列号和窗口大小并建立 TCP 连接。每次建立TCP连接…

蓝桥杯递推与递归法|斐波那契数列|数字三角形|42点问题|数的计算|数的划分(C++)

递归是用来做dfs&#xff0c;是搜索算法的基础 递推是用来做dp部分&#xff0c;及部分其他算法&#xff0c;复杂度较低&#xff0c;不会出现爆栈问题递推法&#xff1a; 递推法是一种在数学和其他领域广泛应用的重要方法&#xff0c;它在计算机科学中被用作一种关键的数值求解…

自动化运维利器Ansible基础(环境部署)

Ansible 介绍及安装 1. 介绍 Ansible 是⼀个 IT ⾃动化⼯具。它能配置系统、部署软件、编 排更复杂的 IT 任务&#xff0c;如连续部署或零停机时间滚动更新。 Ansible ⽤ Python 编写&#xff0c;尽管市⾯上已经有很多可供选择的 配置管理解决⽅案&#xff08;例如 Salt、Pupp…

OpenAI GPT LLMs 高级提示词工程方法汇总

原文地址&#xff1a;An Introduction to Prompt Engineering for OpenAI GPT LLMs Github&#xff1a;Prompt-Engineering-Intro 2023 年 3 月 2 日 提示工程指南 | Prompt Engineering Guide Naive 提示词&#xff1a;带有提示的情感分类器 prompt Decide whether a T…

复合查询【MySQL】

文章目录 复合查询测试表 单表查询多表查询子查询单行子查询多行子查询IN 关键字ALL 关键字ANY 关键字 多列子查询 合并查询 复合查询 测试表 雇员信息表中包含三张表&#xff0c;分别是员工表&#xff08;emp&#xff09;、部门表&#xff08;dept&#xff09;和工资等级表&…

GEE:基于ERA5数据集(U和V风速分量)计算风速的幅值和风向

作者:CSDN @ _养乐多_ 本文将介绍使用Google Earth Engine (GEE)平台提供的API加载ERA5月度数据集,该数据集包含了从1979年至今的全球月度气象数据。然后,定义了一个数据计算函数,用于将U和V风速分量转换为风速的幅值和风向。 结果如下图所示, 文章目录 一、核心函数1…

基于单片机的语音存储与回放系统设计

目 录 摘 要 I Abstract II 引 言 1 1 控制系统设计 3 1.1 系统方案设计 3 1.2 系统工作原理 4 1.2.1 单片机的选择 4 1.2.2 语音芯片的选择 5 2 硬件电路设计 6 2.1 时钟电路 6 2.2 复位电路 6 2.3 显示电路 7 2.4 电源电路 7 2.5 按键模块电路 8 2.6 LM386功放电路 8 2.7 总…

基于深度学习YOLOv8+Pyqt5的抽烟吸烟检测识别系统(源码+跑通说明文件)

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;39抽烟 获取完整源码源文件4000张已标注的数据集配置说明文件 可有偿59yuan一对一远程操作跑通 效果展示 基于深度学YOLOv8PyQt5的抽烟吸烟检测识别系统&#xff08;完整源码跑通说明文件&#xff09; 各文件说明 模型评价…

Seurat 中的数据可视化方法

本文[1]将使用从 2,700 PBMC 教程计算的 Seurat 对象来演示 Seurat 中的可视化技术。您可以从 SeuratData[2] 下载此数据集。 SeuratData::InstallData("pbmc3k")library(Seurat)library(SeuratData)library(ggplot2)library(patchwork)pbmc3k.final <- LoadData(…

【机器学习300问】31、不平衡数据集如何进行机器学习?

一、什么是不平衡的数据集&#xff1f; &#xff08;1&#xff09;认识不平衡数据 假如你正在管理一个果园&#xff0c;这个果园里主要有两种水果——苹果和樱桃。如果苹果树有1000棵&#xff0c;而樱桃树只有10棵&#xff0c;那么在收集果园的果实时&#xff0c;你会得到大量…