您的位置:首页 > 房产 > 建筑 > 网页界面设计作品推荐_做前端开发需要学什么_东莞seo网站排名优化公司_长沙专业seo优化推荐

网页界面设计作品推荐_做前端开发需要学什么_东莞seo网站排名优化公司_长沙专业seo优化推荐

2025/3/14 1:46:52 来源:https://blog.csdn.net/qq_53201790/article/details/145846662  浏览:    关键词:网页界面设计作品推荐_做前端开发需要学什么_东莞seo网站排名优化公司_长沙专业seo优化推荐
网页界面设计作品推荐_做前端开发需要学什么_东莞seo网站排名优化公司_长沙专业seo优化推荐

题目描述
 

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

示例 1:

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

示例 2:

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

 

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成

 力扣代码:

class Solution {
public:// expandAroundCenter 函数通过给定的中心 (left, right) 扩展回文串// 当左指针和右指针的字符相等时,继续扩展,直到找到不相等或越界为止pair<int, int> expandAroundCenter(const string& s, int left, int right) {// 通过 while 循环,扩展回文while (left >= 0 && right < s.size() && s[left] == s[right]) {--left;  // 向左扩展++right; // 向右扩展}// 返回最终的左右指针位置,这两个位置表示的是最大回文子串的左右边界// 注意,退出 while 循环时,left 和 right 已经越界或不相等,因此要返回的是 left + 1 和 right - 1return {left + 1, right - 1};}// longestPalindrome 函数遍历字符串中的每个字符,并尝试以每个字符作为回文中心string longestPalindrome(string s) {int start = 0, end = 0;  // 用来记录最长回文子串的起始和结束位置// 遍历字符串中的每个字符for (int i = 0; i < s.size(); ++i) {// expandAroundCenter 函数可以找到以字符 i 为中心的回文子串auto [left1, right1] = expandAroundCenter(s, i, i);  // 奇数长度的回文子串auto [left2, right2] = expandAroundCenter(s, i, i + 1);  // 偶数长度的回文子串// 更新最大回文子串的起始和结束位置// 如果奇数长度回文子串更长,则更新 start 和 endif (right1 - left1 > end - start) {start = left1;end = right1;}// 如果偶数长度回文子串更长,则更新 start 和 endif (right2 - left2 > end - start) {start = left2;end = right2;}}// 返回最长回文子串return s.substr(start, end - start + 1); // substr(start, length) 返回子串}
};

以上是力扣的官方题解,但是我第一次读起来感觉非常晦涩难懂,就加了一些注释,可能也有新手跟我一开始有一样的困惑,下边是一些当时做这道题有些不明白的点: 

 函数解释:

expandAroundCenter

  • 这是一个辅助函数,给定一个左右中心 leftright,扩展回文串直到遇到不相等的字符或超出字符串边界。
  • 它返回回文串的左右边界,注意由于扩展时,leftright 最后会越过实际的回文子串,因此返回的边界是 left + 1right - 1

longestPalindrome

  • 该函数遍历每个字符,将其作为中心尝试寻找最长的回文子串。
  • 对于每个字符,尝试找到两种情况的回文子串:
    • 奇数长度回文:以该字符为中心,调用 expandAroundCenter(s, i, i)
    • 偶数长度回文:以该字符和下一个字符之间的空隙为中心,调用 expandAroundCenter(s, i, i + 1)
  • 每次调用后,比较回文子串的长度,如果比当前记录的最长回文子串长,就更新起始和结束位置。
  • 最后,使用 substr 返回最长回文子串。

pair操作解释:

pair<int, int> 是 C++ 标准库中 std::pair 的一种使用方式。std::pair 是一个模板类,用于存储两个数据元素,这两个元素可以是任意类型。pair<int, int> 就是一个特定类型的 pair,表示存储两个 int 类型的元素。

 

1. pair<int, int> 的结构

pair<int, int> 实际上是一个包含两个整数的对象,它的结构如下:

pair<int, int> p;

 其中 p.first 是第一个整数,p.second 是第二个整数。你可以通过这两个成员来访问这对值。

 2. 使用示例

#include <iostream>
using namespace std;int main() {// 创建一个 pair,存储两个整数pair<int, int> p = {3, 7};  // 初始化,first = 3, second = 7// 访问 pair 的成员cout << "First: " << p.first << endl;   // 输出 3cout << "Second: " << p.second << endl; // 输出 7// 修改 pair 的成员p.first = 5;p.second = 10;cout << "Updated First: " << p.first << endl;   // 输出 5cout << "Updated Second: " << p.second << endl; // 输出 10return 0;
}

 3. 结构化绑定(C++17及以后)

在 C++17 中,可以使用结构化绑定来简化对 pair 类型的访问。这让我们可以像拆解元组那样访问 pair 的元素。

例如,以下是 pair<int, int> 结合结构化绑定的写法:

#include <iostream>
using namespace std;int main() {pair<int, int> p = {3, 7};  // 初始化 pair// 使用结构化绑定auto [a, b] = p;// 访问拆解后的变量cout << "a: " << a << endl;  // 输出 3cout << "b: " << b << endl;  // 输出 7return 0;
}

 这里,auto [a, b] = p; 是结构化绑定的语法,p 被拆解成两个变量 ab,它们分别对应 p.firstp.second

 

4. pair<int, int> 的常见应用

  • 返回多个值:函数可以返回一个 pair 来同时返回两个相关的值。
  • 映射(Map)操作std::mapstd::unordered_map 中的元素是 pair<const Key, Value>,其中 first 是键,second 是值。
  • 记录坐标、区间、最值等pair 可以用来存储一对相关的数据,例如一个区间的开始和结束位置。

const操作解释:

 

1. const

const 是常量的意思,表示这个变量的值在函数内部不能被修改。对于 const string& s 来说,意味着:

  • 你不能修改 s 所引用的字符串的内容。
  • 你不能让 s 引用另一个字符串。

2. string&

string& 表示 s 是一个引用,即它是对某个 string 类型对象的引用,而不是该对象的副本。

引用是 C++ 中的一种类型,它就像是对象的别名。通过引用,你可以直接访问原始对象,而不需要复制该对象。

3. 常量引用 const string&

  • const& 结合在一起,就意味着“对一个字符串的引用,但不能修改它”。你不能改变 s 引用的字符串内容,但你可以读取它。
  • 由于是引用,这意味着你不需要复制整个字符串,只是借用原始字符串的内存,因此它比传值方式(string s)更加高效,尤其是当字符串较长时。

为什么要使用 const string&

  1. 性能优化:传递大的对象(如字符串)时,如果传递的是引用,而不是副本,会更高效,避免了内存的复制。
  2. 保证不修改数据const 保证函数内部不会修改传入的字符串,符合常量性设计,避免无意间改变数据。
  3. 保持不变性:保证字符串在函数内部不能被修改,使得代码更安全、更容易理解。

 示例:

#include <iostream>
#include <string>
using namespace std;void printString(const string& s) {// 你可以读取字符串,但不能修改它cout << s << endl;// s[0] = 'A'; // 错误:不能修改常量引用
}int main() {string str = "Hello, world!";printString(str); // 传递字符串的常量引用return 0;
}

auto操作解释:

 auto 是 C++11 引入的关键字,用来让编译器根据变量初始化的类型来自动推导出变量的类型。它使代码更加简洁,并且减少了手动指定类型时的出错机会,尤其是在函数返回类型较为复杂时。

在力扣代码中:

auto [left1, right1] = expandAroundCenter(s, i, i);
auto [left2, right2] = expandAroundCenter(s, i, i + 1);

这里的 expandAroundCenter 函数返回了一个 pair<int, int> 类型的值。通过使用 auto,你不需要显式写出返回类型 pair<int, int>,编译器会根据 expandAroundCenter 函数的返回类型自动推导出 left1, right1left2, right2 的类型。

 

为什么选择 auto

  1. 简化代码auto 让你不需要手动声明变量类型(pair<int, int>),这样就能避免类型重复声明,并且保持代码的简洁和可读性。

  2. 避免重复类型声明expandAroundCenter 返回的是 pair<int, int> 类型,手动声明时,你可能需要写出 pair<int, int> left1, right1;,这样显得冗长,使用 auto 可以省略这种重复。

  3. 提高可维护性:如果你修改了 expandAroundCenter 的返回类型(例如改变了返回类型结构),使用 auto 后,你不需要去修改每个相关变量的类型声明,这样使得代码更易于维护。

示例:

 如果以上代码你显式声明类型,而不用 auto,代码会是这样:

pair<int, int> left1, right1;
pair<int, int> left2, right2;
left1 = expandAroundCenter(s, i, i);
right1 = expandAroundCenter(s, i, i + 1);

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com