leetcode:43. 字符串相乘(附加一些C++string其他小练习)

news2024/9/29 11:35:37

目录

一.leetcode:43. 字符串相乘

1.问题描述

2.问题分析

3.问题求解 

二. leetcode:541. 反转字符串 II 

1.问题描述 

2.题解

三. leetcode:125. 验证回文串

1.问题描述

2.双指针法求解 


一.leetcode:43. 字符串相乘

43. 字符串相乘 - 力扣(Leetcode)

1.问题描述

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

示例 1:

输入: num1 = "2", num2 = "3"
输出: "6"

示例 2:

输入: num1 = "123", num2 = "456"
输出: "56088"

注意:

  • 1 <= num1.length, num2.length <= 200
  • num1 和 num2 只能由数字字符组成。
  • num1 和 num2 都不包含任何前导零。 

题解接口:

class Solution
{
public:
    string multiply(string num1, string num2)
    {

    }
};

2.问题分析

  • 关于两个乘积的结果的分析

假设num1为n位数,num2为m位数,则num1与num2的乘积最多为n+m位数。

  •  为了方便计算,我们可以先将数字字符串转换成相应的数字数组

3.问题求解 

  •  第一步

封装一个转换函数数字字符串倒序存入相应的数字数组(倒不倒序其实无所谓)

    void convert(string& nums, int* const Anum)
    {
        int end = nums.size();
        int start = 0;
        for (start = 0; start < nums.size(); start++)
        {
            Anum[start] = nums[end - 1]-'0';   //-'0'是为了将字符转换为相应数字
            end--;
        }
    }
  • 第二步

动态开辟一个数组Anum1用于倒序存储字符串num1对应的数字

动态开辟一个数组Anum2用于倒序存储字符串num2对应的数字

动态开辟一个数组Answer用于倒序存储两数相乘的计算结果

创建一个string StrAns用于存储最后要输出的结果。

        int ptrnum1 = num1.size();
        int ptrnum2 = num2.size();
        int* const Anum1 = new int[ptrnum1];
        int* const Anum2 = new int[ptrnum2];
        int* const Answer = new int[ptrnum1 + ptrnum2]{0};//存储结果的数组中所有元素初始化为0
        string StrAns;
        StrAns.reserve(ptrnum1 + ptrnum2); 
        convert(num1,Anum1);
        convert(num2,Anum2);

注意利用reserve接口提前为StrAns字符串预留好存储空间,避免后续扩容增加时间消耗

  • 第三步(算法部分)

基本思路是用三个数组模拟竖式乘法:

循环框架: 

        for(i=0;i<ptrnum1;i++)
        {
            for(j=0;j<ptrnum2;j++)
            {
                ;
            }
            ;
        }

变量limitAnswer用来记录计算结果的位数

变量tem用来保存当前(两个数某两位的乘积+进位+存储结果的数组的原位)的和;

变量carry用来保存进位;

        int limitAnswer = 0;
        int i=0;
        int j=0;
        int tem=0;
        int carry=0;
        for(i=0;i<ptrnum1;i++)
        {
            for(j=0;j<ptrnum2;j++)
            {
                tem = carry + Anum1[i]*Anum2[j] + Answer[j+i];
                Answer[i+j]=tem%10;           //tem的个位就是当前Answer对应位的取值
                carry = tem/10;               //tem取十位数得到下一位的进位
            }
            if(carry)
            {
                Answer[i+j]=carry;//该轮循环计算完后若还存在进位则将进位置于当前结果的最高位
                                  //的下一位
                carry=0;
                limitAnswer=i+j;  //记录当前结果的位数
            }
            else
            {
                limitAnswer = i+j-1;//记录当前结果的位数
            }
            
        }

算法动画演示:

代码段实际计算过程中Answer中的数字是逆序存储的

  •  第四步

将结果倒序存入用于作返回值的对象StrAns的字符串中:

        for(i=limitAnswer;i>=0;--i)
        {
            StrAns += (Answer[i]+'0');
        }

完整题解代码:

class Solution
{
public:
    void convert(string& nums, int* const Anum)
    {
        int end = nums.size();
        int start = 0;
        for (start = 0; start < nums.size(); start++)
        {
            Anum[start] = nums[end - 1]-'0';
            end--;
        }
    }
    string multiply(string num1, string num2)
    {
        if("0"==num1||"0"==num2)
        {
            return "0";
        }
        int ptrnum1 = num1.size();
        int ptrnum2 = num2.size();
        int* const Anum1 = new int[ptrnum1];
        int* const Anum2 = new int[ptrnum2];
        int* const Answer = new int[ptrnum1 + ptrnum2]{0};
        string StrAns;
        StrAns.reserve(ptrnum1 + ptrnum2);
        convert(num1,Anum1);
        convert(num2,Anum2);

        int limitAnswer = 0;
        int i=0;
        int j=0;
        int tem=0;
        int carry=0;
        for(i=0;i<ptrnum1;i++)
        {
            for(j=0;j<ptrnum2;j++)
            {
                tem = carry + Anum1[i]*Anum2[j] + Answer[j+i];
                Answer[i+j]=tem%10;
                carry = tem/10;
            }
            if(carry)
            {
                Answer[i+j]=carry;
                carry=0;
                limitAnswer=i+j;
            }
            else
            {
                limitAnswer = i+j-1;
            }
        }

        for(i=limitAnswer;i>=0;--i)
        {
            StrAns += (Answer[i]+'0');
        }
        return StrAns;
    }
};

 

二. leetcode:541. 反转字符串 II 

541. 反转字符串 II - 力扣(Leetcode) 

1.问题描述 

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样 

2.题解

class Solution 
{
public:
    string reverseStr(string s, int k) 
    {
        int n = s.length();
        for (int i = 0; i < n; i += 2 * k) 
        {
            reverse(s.begin() + i, s.begin() + min(i + k, n));
        }
        return s;
    }
};
  • min是C++标准库命名空间std中的一个函数,用于返回两个数中的较小值
  • reverse是C++标准库命名空间std中的一个函数,用于string对象的字符串逆序,形参为两个string对象的迭代器(初学者可以类比为指针)
  • 将迭代器类比为指针:  s.begin()相当于指向string字符串首元素的指针 

三. leetcode:125. 验证回文串

1.问题描述

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个回文串 。

给你一个字符串 s,如果它是回文串 ,返回 true ;否则,返回 false 

示例 :

输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。

2.双指针法求解 

本题利用双指针法可以同时节省时间和空间:

  • 创建两个下标变量,其中一个起始位置指向字符串首字符,另外一个起始位置指向字符串末尾字符。
  • 起始位置指向字符串首字符的指针向后遍历,起始位置指向字符串末尾字符的指针向前遍历

题解代码:

class Solution 
{
public:
    bool isword (char & c)             //封装一个字符判断函数
    {
        if((c>='a'&&c<='z') ||( c>='0'&&c<='9'))
        {
            return true;
        }
        else if((c>='A'&&c<='Z'))     //大写转小写
        {
            c+=32;
            return true;
        }
        return false;
    }
    bool isPalindrome(string s) 
    {
        int right= s.size()-1;
        int left=0;
        while(right>left)
        {
            while(right>left && !isword(s[left]))  //左指针跳过非数字字母字符
            {
                left++;
            }
            while(right>left && !isword(s[right])) //右指针跳过非数字字母字符
            {
                right--;
            }
            if(s[left]!=s[right])                  //若过程中有字符不相同则说明不是回文串
            {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
};

 注意内层循环条件中right>left不能少。

 

 

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

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

相关文章

数据结构(括号匹配与表达式计算)

目录 括号配对 括号匹配算法 表达式计算 后缀式的计算 中缀式转后缀式 括号配对 编译器做语法检查的任务之一是检查符号是否配对&#xff0c;最简单的符号匹配问题是括号是否匹配&#xff0c;如开括号( 及{ 后面必须依次跟随相应的闭括号 }及 )。 如下段程序中的括号、引号…

谷歌竞价账户效果不好的原因?

很多外贸企业喜欢用谷歌竞价来推广自己的网站&#xff0c;提升自己的竞争力。是一种能很快看到效果的宣传方式。但是很多公司在谷歌竞价上投入了大量的资金&#xff0c;却收效甚微。为什么&#xff1f;下面我们来看看如何解决我们在google竞价推广中会遇到的一些问题。很多人在…

Linux的文件权限理解

目录 前言 1、用户、用户组、其他人 1.1用户、用户组、其他人之间的概念理解 1.2Linux系统中有用户身份与用户组记录的文件 2、Linux文件权限概念 第一列 第二列 第三列 第四列 第五列 第六列 第七列 Linux文件权限的重要性 3、Linux的目录与文件的权限意义 权限…

计算机图形学 第5章 二维变换与裁剪到Cohen-Sutherland直线裁剪算法

目录学习目标前驱知识规范化齐次坐标二维几何变换矩阵物体变换与坐标变换二维几何变换二维图形基本几何变换矩阵平移变换矩阵比例变换矩阵旋转变换矩阵反射变换矩阵错切变换矩阵二维仿射变换二维复合变换相对于任意方向的二维几何变换二维图形裁剪世界坐标系2.用户坐标系观察坐…

VSCode中设置Python语言自动格式化的方案

安装Python扩展 在VSCode的扩展&#xff08;Externsions&#xff09;中使用下面命令检索Python扩展 category:debuggers Python 打开一个Python文件&#xff0c;可以在VSCode的右下角看到运行环境。 安装PEP8 python3.10 -m pip install -U autopep8 安装Flake8 python3.10 …

上百个数字经济新场景 低代码完美搭建 实现项目落地

数字经济 自人类社会进入信息时代以来&#xff0c;数字技术的快速发展和广泛应用衍生出数字经济(Digital Economy)。与农耕时代的农业经济&#xff0c;以及工业时代的工业经济大有不同&#xff0c;数字经济是一种新的经济、新的动能&#xff0c;新的业态&#xff0c;其引发了社…

MicroBlaze系列教程(3):AXI_TIMER的使用

文章目录 @[toc]AXI_TIMER简介常用函数使用示例参考资料工程下载本文是Xilinx MicroBlaze系列教程的第3篇文章。 AXI_TIMER简介 AXI_TIMER支持两路可编程32位计数器,可以配置为中断、捕获、PWM模式,两个32位计数器可以级联为一个64位计数器。 IP核支持的最高频率: 常用…

nacos 服务发现获取列表源码分析

nacos 服务发现获取列表源码是注册中心最重要的技术点之一&#xff0c;其获取服务列表理论上是在首次接口调用时获取&#xff0c;有时候配置饥饿加载&#xff0c;即服务启动时就获取服务列表&#xff1a;今天我们从一个入口解析获取配置列表; 一、客户端源码 1、自动装配&…

推荐系统之推荐缓存服务

5.6 推荐缓存服务 学习目标 目标 无应用 无 5.6.1 待推荐结果的redis缓存 目的&#xff1a;对待推荐结果进行二级缓存&#xff0c;多级缓存减少数据库读取压力步骤&#xff1a; 1、获取redis结果&#xff0c;进行判断 如果redis有&#xff0c;读取需要推荐的文章数量放回&am…

(深度学习快速入门)第四章第一节:基础图像处理知识

文章目录一&#xff1a;位图和矢量图二&#xff1a;图像分辨率三&#xff1a;颜色模式&#xff08;1&#xff09;RGB&#xff08;2&#xff09;HSB&#xff08;2&#xff09;灰度图四&#xff1a;通道五&#xff1a;亮度、对比度和饱和度六&#xff1a;图像平滑和锐化&#xff…

D3股权穿透图

前言&#xff1a;最近做了一个项目&#xff0c;主要就是实现各种类似企查查的各种图谱&#xff0c;欢迎交流。后期将完成的谱图全部链接上&#xff0c;目前已大致实现了&#xff1a; 【企业关系图谱】、【企业构成图谱】、【股权穿透图】、【股权结构图】、【关联方认定图】 准…

【蓝桥杯基础题】2018年省赛—日志统计

&#x1f451;专栏内容&#xff1a;蓝桥杯刷题⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录一、题目描述1.问题描述2.输入格式3.输出格式4.一个例子二、题目分析1、暴力法2、双指针三、代码汇总1、暴力代码汇总2、双…

【Mysql第一期 数据库概述】

文章目录1. 为什么要使用数据库2. 数据库与数据库管理系统2.1 数据库的相关概念2.2 数据库特点2.3SQL优点3.常见的数据库介绍1.Oracle2.SQL Server3.MySQL4.Access5.DB26.PostgreSQL7.SQLite8.informix4. MySQL介绍4.1Mysql重大历史事件4.2 关于MySQL 8.04.3 Why choose MySQL?…

linux内核读文件代码分析

linux下“一切皆文件”,所有设备都可以被抽象成文件,用户态可以通过open、read、write、llseek等api操作一个文件,通过系统调用进入内核态,最终访问到pagecache/磁盘上的数据,然后返回给用户态。 kernel version:v6.2-rc4 社区master主干 用户态应用程序调用read接口,通…

【转载】车载传感器与云端数据交换标准SensorIS的理解与使用

原文 https://zhuanlan.zhihu.com/p/386277784 1、什么是SensorIS?SensorIS全称是Sensor Interface Specification&#xff0c;翻译为中文就是传感器接口规范&#xff0c;是由来自全球汽车行业的主机厂、地图和数据提供商、传感器制造商和电信运营商共同组成的开放团体发布的一…

JavaEE day10 初识SpringMVC

JSON简介 JSON &#xff1a;JavaScript Object Notation JS对象表示法 是轻量级的文本数据交换格式&#xff0c;但是JSON仍然独立于语言和平台。其解析器和库支持许多不同的编程语言。目前非常多的动态编程语言&#xff08;java&#xff0c;PHP&#xff09;都支持JSON。JSON…

禅道好用吗?优缺点及类似10大项目管理系统介绍

类似禅道的十大项目管理软件&#xff1a;1、一站式研发项目管理软件PingCode&#xff1b;2、通用型项目协作工具Worktile&#xff1b;3、开源项目管理软件Redmine&#xff1b;4、免费项目管理软件Trello&#xff1b;5、无代码项目管理软件Monday&#xff1b;6、IT项目追踪管理工…

面试宝典-数据库基础

数据库基础前言一、数据库1.1 sql练习题1.2 sql语句执行顺序1.3 sql语句编写前言 本文主要记录B站视频视频链接的内容&#xff0c;做到知识梳理和总结的作用&#xff0c;项目git地址。 一、数据库 1.1 sql练习题 user表数据: idusername1张三2李四3王五4小刘 user_role表数…

CrackQL:一款功能强大的图形化密码爆破和模糊测试工具

关于CrackQL CrackQL是一款功能强大的图形化密码爆破和模糊测试工具&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以针对密码安全和应用程序安全进行渗透测试。 除此之外&#xff0c;CrackQL同时也是一款通用的GraphQL渗透测试工具&#xff0c;它可以控制速率限制…

垃圾分类智能分析系统 yolov7

垃圾分类智能分析系统应用pythonyolov7网络模型深度学习识别技术&#xff0c;自动识别违规投放行为并现场进行语音提示实时预警。如垃圾满溢抓拍预警、人脸识别、工服识别、厨余垃圾混投未破袋识别预警、垃圾落地识别预警、人来扔垃圾语音提醒等。我们选择当下YOLO最新的卷积神…