Offer必备算法16_字符串_四道力扣题详解(由易到难)

news2024/12/28 4:45:04

目录

①力扣14. 最长公共前缀

解析代码1(两两比较)

解析代码2(统一比较)

②力扣5. 最长回文子串

解析代码(中心拓展)

③力扣67. 二进制求和

解析代码

④力扣43. 字符串相乘

解析代码(无进位相乘)

本篇完。


①力扣14. 最长公共前缀

14. 最长公共前缀

难度 简单

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"

示例 2:

输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

提示:

  • 1 <= strs.length <= 200
  • 0 <= strs[i].length <= 200
  • strs[i] 仅由小写英文字母组成
class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {

    }
};

解析代码1(两两比较)

        解法1(两两比较): 可以先找出前两个的最长公共前缀,然后拿这个最长公共前缀依次与后面的字符串比较,这样就可以找出所有字符串的最长公共前缀。

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        string ret = strs[0];
        for(int i = 1; i < strs.size(); ++i)
        {
            ret = TowlongestCommonPrefix(ret, strs[i]);
        }
        return ret;
    }

    string TowlongestCommonPrefix(string& str1, string& str2)
    {
        if(str1.size() > str2.size())
            swap(str1, str2);

        for(int i = 0; i < str1.size(); ++i)
        {
            if(str1[i] == str2[i])
                continue;
            else
                return str1.substr(0, i);
        }
        return str1;
    }
};

解析代码2(统一比较)

        解法2(统一比较):题目要求多个字符串的公共前缀,我们可以逐位比较这些字符串,哪一位出现了不同,就在哪一位截止。

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        string ret = "";
        sort(strs.begin(), strs.end());
        for(int i = 0; i < strs[0].size(); ++i) // 遍历最小的字符串
        {
            int j = 1; // 第二行开始依次和第一行比较
            while(j < strs.size() && strs[0][i] == strs[j][i])
            {   // 注意j不要越界
                ++j;
            }
            if(j == strs.size())
            {
                ret += strs[0][i];
            }
            else
            {
                break;
            }
        }
        return ret;
    }
};

②力扣5. 最长回文子串

5. 最长回文子串

难度 中等

给你一个字符串 s,找到 s 中最长的回文子串。

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成
class Solution {
public:
    string longestPalindrome(string s) {

    }
};

解析代码(中心拓展)

        暴力解法是O(N^3),对于一个子串而言,如果它是回文串,并且长度大于 2,那么将它首尾的两个字母去除之后,它仍然是个回文串。如此这样去除,一直除到长度小于等于 2 时呢?长度为 1 的,自身与自身就构成回文,而长度为 2 的,就要判断这两个字符是否相等了。

        从这个性质可以反推出来,从回文串的中心开始,往左读和往右读也是一样的。那么,是否可以枚举回文串的中心呢? 从中心向两边扩展,如果两边的字母相同,就可以继续扩展,如果不同,就停止扩展。这样只需要一层 for 循环,就可以完成之前两层 for 循环的工作量。

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.size(), begin = 0, maxlen = 0;
        for(int i = 0; i < n; ++i)
        {
            int left = i, right = i, cnt = 0; // 奇数长度拓展
            while(left >= 0 && right < n && s[left] == s[right])
            {
                --left;
                ++right;
                cnt = right - left - 1;
            }
            if(cnt > maxlen)
            {
                begin = left + 1;
                maxlen = cnt;
            }

            left = i, right = i + 1, cnt = 0; // 偶数长度拓展
            while(left >= 0 && right < n && s[left] == s[right])
            {
                --left;
                ++right;
                cnt = right - left - 1;
            }
            if(cnt > maxlen)
            {
                begin = left + 1;
                maxlen = cnt;
            }
        }
        return s.substr(begin, maxlen);
    }
};

③力扣67. 二进制求和

67. 二进制求和

难度 简单

给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。

示例 1:

输入:a = "11", b = "1"
输出:"100"

示例 2:

输入:a = "1010", b = "1011"
输出:"10101"

提示:

  • 1 <= a.length, b.length <= 10^4
  • a 和 b 仅由字符 '0' 或 '1' 组成
  • 字符串如果不是 "0" ,就不含前导零
class Solution {
public:
    string addBinary(string a, string b) {

    }
};

解析代码

        思路是模拟十进制中列竖式计算两个数之和的过程。但是这是二进制求和,不是逢十进一,而是逢二进一。

class Solution {
public:
    string addBinary(string a, string b) {
        if(a.size() > b.size())
            swap(a, b); // 让b是长的

        string ret = "" ;
        int val = 0, carry = 0;
        for(int i = b.size()-1, j = a.size()-1; i >= 0 ; --i)
        {
            if(j >= 0)
                val = (a[j--] - '0') + (b[i] - '0') + carry;
            else
                val = (b[i] - '0') + carry;
            carry = val / 2;
            ret += ((val % 2) + '0');
        }
        if(carry)
            ret += (carry + '0');
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

④力扣43. 字符串相乘

43. 字符串相乘

难度 中等

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

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

示例 1:

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

示例 2:

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

提示:

  • 1 <= num1.length, num2.length <= 200
  • num1 和 num2 只能由数字组成。
  • num1 和 num2 都不包含任何前导零,除了数字0本身。
class Solution {
public:
    string multiply(string num1, string num2) {

    }
};

解析代码(无进位相乘)

解法1是模拟小学的列竖式运算,直接进位相加,这样要处理后面的0,很麻烦

        这里看一种优化过的无进位相乘的解法:是在计算两数相乘的时候,先不考虑进位,等到所有结果计算完毕之后,再去考虑进位。如下图:

可以自己模拟没优化的解法,官方题解有答案,这里模拟无进位相乘的解法:

class Solution {
public:
    string multiply(string num1, string num2) {
        int n1 = num1.size(), n2 = num2.size();
        vector<int> tmp(n1 + n2 - 1);
        reverse(num1.begin(), num1.end());
        reverse(num2.begin(), num2.end());

        for(int i = 0; i < n1; ++i)
        {
            for(int j = 0; j < n2; ++j)
            {
                tmp[i+j] += (num1[i] - '0') * (num2[j] - '0');
            }
        }
        string ret = "";
        int carry = 0;
        for(auto& e : tmp)
        {
            cout << e << " ";
            ret += ((e + carry) % 10 + '0');
            carry = (e + carry) / 10; 
        }
        if(carry)
            ret += (carry + '0');

        while(ret.size() > 1 && ret.back() == '0') 
            ret.pop_back(); // 处理前导0

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

本篇完。

下一篇动态规划类型的是子数组子串dp,

下下篇是栈的相关OJ。

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

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

相关文章

Kotlin runBlocking CoroutineScope synchronized简单死锁场景

Kotlin runBlocking CoroutineScope synchronized简单死锁场景 import kotlinx.coroutines.*fun main(args: Array<String>) {runBlocking {val lock1 Any()val lock2 Any()CoroutineScope(Dispatchers.IO).launch {repeat(10) {println("A-$it 申请 lock1...&quo…

【linux】环境基础|开发工具|gcc|yum|vim|gdb|make|git

目录 ​编辑 Linux 软件包管理器 yum 软件包: 操作&#xff1a; 拓展&#xff1a;lrzsz简介 Linux开发工具 Linux编辑器-vim使用 vim 的基本概念 命令模式 插入模式 底行模式 vim 命令模式的操作指令 vim 底行模式的操作命令 Linux编译器-gcc/g使用 功能 格…

Java学习六—面向对象

一、关于面向对象 1.1简介 Java 是一种面向对象编程语言&#xff0c;其核心思想是面向对象编程&#xff08;Object-Oriented Programming&#xff0c;OOP&#xff09;。 面向对象编程是一种程序设计范式&#xff0c;它将数据与操作数据的方法&#xff08;函数&#xff09;捆…

有了std::thread,为什么还需要引入std::jthread?

C进阶专栏&#xff1a;http://t.csdnimg.cn/HGkeZ 目录 1.前言 2.std::is_invocable_v 3.std::jthread 3.1.构造函数 3.2.std::jthread无需join/detach使用实例 3.3.std::jthread处理外部请求中断实 3.4.处理中断请求示例代码 4.特性 5.总结 1.前言 C11以来提供了C原…

蓝桥杯刷题(十二)

1.答疑 代码 n int(input()) L [] for i in range(n):a,b,c map(int,input().split())A ab # 进入和答疑时间B abc # 个人总用时L.append([A,B]) L.sort(keylambda x:x[1]) # 个人总用时短的优先 ans tmp 0 # ans为发消息时刻&#xff0c;tmp为前一个人的总用时 for i …

【位运算】【 数学】【 哈希映射】2857. 统计距离为 k 的点对

本文涉及知识点 位运算 数学 哈希映射 LeetCode 2857. 统计距离为 k 的点对 给你一个 二维 整数数组 coordinates 和一个整数 k &#xff0c;其中 coordinates[i] [xi, yi] 是第 i 个点在二维平面里的坐标。 我们定义两个点 (x1, y1) 和 (x2, y2) 的 距离 为 (x1 XOR x2) …

数学建模-邢台学院

文章目录 1、随机抽取的号码在总体的排序2、两端间隔对称模型 1、随机抽取的号码在总体的排序 10个号码从小到大重新排列 [ x 0 , x ] [x_0, x] [x0​,x] 区间内全部整数值 ~ 总体 x 1 , x 2 , … , x 10 总体的一个样本 x_1, x_2, … , x_{10} ~ 总体的一个样本 x1​,x2​,……

【Leetcode每日一题】 递归 - 反转链表(难度⭐)(36)

1. 题目解析 题目链接&#xff1a;206. 反转链表 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 一、递归函数的核心任务 递归函数的主要职责是接受一个链表的头指针&#xff0c;并返回该链表逆序后的新头结点。递归…

两台电脑简单的通信过程详解(局域网,同网段)

来源&#xff1a; https://www.bilibili.com/video/BV1BA411373b/ 一、原理 描述过程&#xff1a;分别以PC1、PC2、PC2、PC1的角度 二、eNSP测试 1.连接设备 2.查看PC1情况 3.打开抓包后&#xff0c;再ping一下PC2 4.PC1发送ARP报文 broadcast 意思为广播(IP都是f,意为255…

return code 1 from org.apache.hadoop.hive.ql.ddl.DDLTask

Bug信息 Error: Error while compiling statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.ddl.DDLTask (state=08S01,code=1)Bug产生的代码 修复hive表分区: msck repair table xxxBug原因排查 分区数量过大 这个是网上查看的说如果一次…

2024.3.21 如何将idea的注释设置为在首字母前开始而不是句首

2024.3.21 如何将idea的注释设置为在首字母前开始而不是句首 两种写法的差异 修改办法 将右下角的勾去掉即可。

redis关联和非关联

1.1.2.关联和非关联 传统数据库的表与表之间往往存在关联&#xff0c;例如外键&#xff1a; 而非关系型数据库不存在关联关系&#xff0c;要维护关系要么靠代码中的业务逻辑&#xff0c;要么靠数据之间的耦合&#xff1a; {id: 1,name: "张三",orders: [{id: 1,ite…

手拉手整合Springboot3+RocketMQ2.3

RocketMQ 基本概念 消息模型Message Model RocketMQ 主要由 Producer、Broker、Consumer 三部分组成&#xff0c;其中 Producer 负责生产消息&#xff0c;Consumer 负责消费消息&#xff0c;Broker 负责存储消息。Broker 在实际部署过程中对应一台服务器&#xff0c;每个 Bro…

【报错】使用gradio渲染html页面无法加载本地图片

【报错】使用gradio渲染html页面无法加载本地图片 【报错】使用gradio渲染html页面无法加载本地图片[HTML] how to load local image by html output #884成功解决 【报错】使用gradio渲染html页面无法加载本地图片 在使用gradio框架渲染html页面&#xff0c;使用绝对路径&quo…

获取cookie

在Servlet9里设置cookie 在Servlet10里进行获取 访问Servlet9.do&#xff0c;再访问Servlet10.do

图书馆RFID(射频识别)数据模型压缩/解压缩算法实现小工具

1. 前言 最近闲来无聊&#xff0c;看了一下《图书馆射频识别数据模型第1部分&#xff1a;数据元素的设置及应用规则》以及《图书馆射频识别数据模型第2部分&#xff1a;基于ISO/IEC 15962的数据元素编码方案》&#xff0c;决定根据上面的编码方法实现一下该算法&#xff0c;于…

PyTorch 深度学习(GPT 重译)(五)

十二、通过指标和增强改进训练 本章涵盖 定义和计算精确率、召回率以及真/假阳性/阴性 使用 F1 分数与其他质量指标 平衡和增强数据以减少过拟合 使用 TensorBoard 绘制质量指标图 上一章的结束让我们陷入了困境。虽然我们能够将深度学习项目的机制放置好&#xff0c;但实…

聚类算法之层次聚类(Hierarchical Clustering)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 层次聚类是一种非常独特和强大的聚类方法&#xff0c;与众多其他的聚类技术相比&#xff0c;它不仅为数据集提供了一个划分&#xff0c;还给出了…

3d模型文件导入时没颜色---模大狮模型网

导入3D模型文件时没有颜色显示通常是由于软件在显示模型时未正确解释颜色信息。这可能是由于模型文件本身没有包含颜色信息&#xff0c;或者是软件在导入过程中未正确处理颜色数据所致。 以下是一些可能的解决方法&#xff1a; 检查3D模型文件&#xff1a;首先&#xff0c;确保…

网络简略总结

目录 一、三次握手 四次挥手 1、三次握手:为了建立长链接进行交互即建立一个会话,使用http/https协议 2、四次挥手是一个断开连接释放服务器资源的过程 3、如果已经建立了连接,但是客户端突然出现故障了怎么办? 4、谁可以中断连接?客户端还是服务端还是都可以? 5、…