C++ 字符串OJ

news2025/1/13 13:40:16

目录

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;否则,返回去除前导零后的结果字符串。

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

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

相关文章

多域名证书和泛域名证书的区别

多域名证书是一种SSL/TLS证书&#xff0c;其特殊之处在于它可以在同一证书中添加多个域名。这些域名可以是不同的主机名或完全不同的域。与传统的SSL证书只能用于一个域名相比&#xff0c;多域名证书提供了为多个域名提供安全保障的便利。 多域名证书的主要优势包括&#xff1…

matplotlib-直方图

日期&#xff1a;2024.03.114 内容&#xff1a;将matplotlib的常用方法做一个记录&#xff0c;方便后续查找。 # 引入需要的库 from matplotlib import pyplot as plt import numpy as np# 设置画布大小 plt.figure(figsize (20,8),dpi 200)# 全局设置中文字体 plt.rcParams…

【六】【算法分析与设计】二分查找

69. x 的平方根 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。 由于返回类型是整数&#xff0c;结果只保留 整数部分 &#xff0c;小数部分将被 舍去 。 注意&#xff1a;不允许使用任何内置指数函数和算符&#xff0c;例如 pow(x, 0.5) 或者 x ** 0.5 。 示…

案例分析:分库分表后,我的应用崩溃了

今天我们主要分析一个案例&#xff0c;那就是分库分表后&#xff0c;我的应用崩溃了。 前面介绍了一种由于数据库查询语句拼接问题&#xff0c;而引起的一类内存溢出。下面将详细介绍一下这个过程。 假设我们有一个用户表&#xff0c;想要通过用户名来查询某个用户&#xff0…

阿里云价格战的背后,难以言说附送阿里云服务器优惠价格明细表

2024阿里云服务器优惠活动政策整理&#xff0c;阿里云99计划ECS云服务器2核2G3M带宽99元一年、2核4G5M优惠价格199元一年&#xff0c;轻量应用服务器2核2G3M服务器61元一年、2核4G4M带宽165元1年&#xff0c;云服务器4核16G10M带宽26元1个月、149元半年&#xff0c;云服务器8核…

leetcode110.平衡二叉树

之前没有通过的样例 return语句只写了一个 return abs(l-r)<1缺少了 isBalanced(root->left)&&isBalanced(root->right);补上就好了 class Solution { public:bool isBalanced(TreeNode* root) {if(!root){return true;}int lgetHeight(root->left);i…

阿里云国际配置DDoS高防(非中国内地)加速线路

DDoS高防&#xff08;非中国内地&#xff09;加速线路只能与DDoS高防&#xff08;非中国内地&#xff09;保险版或无忧版实例结合使用。您将业务&#xff08;部署在中国内地以外地域&#xff09;接入DDoS高防&#xff08;非中国内地&#xff09;实例防护后&#xff0c;可以通过…

upload 上传文件后在下次弹框打开时清空上次上传的内容

文章目录 需求分析 需求 upload 上传文件后在下次弹框打开时清空上次上传的内容 分析 arco-design 暂时无法实现该需求&#xff0c;所以继续使用了 elementPlus 的解决方案 获取 Token const getToken () > {return localStorage.getItem(TOKEN_KEY); };页面 <a-f…

2024年将人力RPO项目当蓝海项目吗?

随着科技的快速发展和全球化趋势的加强&#xff0c;人力资源外包(RPO)项目在过去的几年中异军突起&#xff0c;成为企业优化人力资源配置、降低运营成本的重要手段。然而&#xff0c;到了2024年&#xff0c;我们是否还能将人力RPO项目视为一片尚待开发的蓝海呢? 从市场角度来看…

Ansible管理主机的清单------------inventory

一、 Ansible组成 INVENTORY&#xff1a;Ansible管理主机的清单 /etc/ansible/hosts 需要管理的服务清单,(将你需要管理的主机 、地址 或者名字 写入此文件) MODULES&#xff1a;Ansible执行命令的功能模块&#xff0c;多数为内置核心模块&#xff0c;也可自定义 PLUGINS&…

C goto 语句

C 语言中的 goto 语句允许把控制无条件转移到同一函数内的被标记的语句。 注意&#xff1a;在任何编程语言中&#xff0c;都不建议使用 goto 语句。因为它使得程序的控制流难以跟踪&#xff0c;使程序难以理解和难以修改。任何使用 goto 语句的程序可以改写成不需要使用 goto 语…

DL-丙氨酸(DL-Alanine)为维生素B6原材料 直接发酵法有望成为其主流制备方法

DL-丙氨酸&#xff08;DL-Alanine&#xff09;为维生素B6原材料 直接发酵法有望成为其主流制备方法 丙氨酸可分为D-丙氨酸、L-丙氨酸以及DL-丙氨酸三种类型。DL-丙氨酸又称DL-Alanine&#xff0c;指D-丙氨酸和L-丙氨酸的外消旋混合物。DL-丙氨酸外观呈无色至白色针状结晶或结晶…

前端框架vue的样式操作,以及vue提供的属性功能应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

关于原型的一些总结

猛然发现太久没去复习了&#xff0c;于是复习了一些知识&#xff0c;顺便冒个泡。本次主要总结的知识点关于原型&#xff0c;再文章后半部分有原型相关的题&#xff0c;感兴趣的可直接观看。 一、原型 1.什么是原型 简单理解&#xff0c;原型就是一个对象&#xff0c;通过原…

【MySQL性能优化】- 一文了解MVCC机制

MySQL理解MVCC &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &#x1f31d;分享学习心得&#xff0c;欢迎指正&#xff…

压缩json字符串

GZIPOutputStream 需要关闭&#xff0c;而 ByteArrayOutputStream 不需要关闭。具体原因如下&#xff1a; GZIPOutputStream&#xff1a;GZIPOutputStream是一种过滤流&#xff0c;它提供了将数据压缩为GZIP格式的功能。当使用此类的实例写入数据时&#xff0c;它会对数据进行压…

Seata:实现分布式事务的利器

Seata&#xff1a;实现分布式事务的利器 Seata是一种开源的分布式事务解决方案&#xff0c;旨在解决分布式系统中的事务一致性问题。本文将介绍Seata的概念和原理&#xff0c;探讨其在分布式应用程序中的应用场景&#xff0c;并讨论其对于构建可靠的分布式系统的重要性。 Seata…

网赚人,为什么都退圈了?

今儿的话题多少有些悲观。 因为曾经辉煌的网赚圈也开始下滑&#xff0c;从没想过这一天会来的如此之快。最近一直说经济下行影响实体&#xff0c;我想着跟咱互联网人没关系啊&#xff0c;他们做实体的只针对本地客户&#xff0c;咱互联网人针对全国客户。还怕没人了&#xff1…

让短视频博主脾气变好的5款工具!

啊啊啊啊&#xff01;就想问几句&#xff01;谁在职场上脾气变差了&#xff01; 虽然在职场上总会有几天不想上班也是比较正常的事情&#xff0c; 但有的工作做着就有种摔鼠标发疯&#xff01; 考虑中不少做短视频博主一直想用却不知道的工具&#xff0c;也是专门给大家整理…

iTOP-3588开发板快速启动手册Windows安装串口终端调试串口常见问题(一)

2.4.1 设备管理器找不到端口 问题一&#xff1a;win10或者win11设备管理器找不到端口&#xff0c;怎么办&#xff1f; 解决方法&#xff1a; 一 可能是被隐藏了 1 首先进入到“设备管理器”中&#xff0c;找到如下图的位置。 2 点击“查看”&#xff0c;并找到的“显示隐藏…