您的位置:首页 > 房产 > 建筑 > 360官网入口_网站建设企业营销_公众号运营_莆田百度seo公司

360官网入口_网站建设企业营销_公众号运营_莆田百度seo公司

2025/4/30 16:22:23 来源:https://blog.csdn.net/2302_80871796/article/details/146046467  浏览:    关键词:360官网入口_网站建设企业营销_公众号运营_莆田百度seo公司
360官网入口_网站建设企业营销_公众号运营_莆田百度seo公司

一、面试题 08.01. 三步问题 - 力扣(LeetCode)

算法代码:

class Solution {
public:const int MOD = 1e9 + 7;int waysToStep(int n) {// 1. 创建 dp 表// 2. 初始化// 3. 填表// 4. 返回// 处理边界情况if (n == 1 || n == 2)return n;if (n == 3)return 4;vector<int> dp(n + 1);dp[1] = 1, dp[2] = 2, dp[3] = 4;for (int i = 4; i <= n; i++)dp[i] = ((dp[i - 1] + dp[i - 2]) % MOD + dp[i - 3]) % MOD;return dp[n];}
};

        这段代码的目的是计算上楼梯的方式数,每次可以走1步、2步或3步。代码使用了动态规划(DP)来解决这个问题。下面是代码的详细思路:

1. 创建 DP 表

  • 使用一个数组 dp 来存储每个台阶对应的上楼梯方式数。

  • dp[i] 表示上到第 i 个台阶的方式数。

2. 初始化

  • 对于前三个台阶,直接初始化:

    • dp[1] = 1:只有一种方式(走1步)。

    • dp[2] = 2:有两种方式(1+1 或 2)。

    • dp[3] = 4:有四种方式(1+1+1, 1+2, 2+1, 3)。

3. 填表

  • 从第4个台阶开始,每个台阶的方式数等于前三个台阶方式数的和:

    • dp[i] = dp[i-1] + dp[i-2] + dp[i-3]

  • 由于结果可能非常大,每次计算后都对 MOD 取模,防止溢出。

4. 返回结果

  • 最终返回 dp[n],即上到第 n 个台阶的方式数。

边界情况处理

  • 如果 n 是1、2或3,直接返回对应的值,避免不必要的计算。

代码优化

  • 由于每次只需要前三个状态,可以优化空间复杂度,使用三个变量代替整个 dp 数组。

优化后的代码

class Solution {
public:const int MOD = 1e9 + 7;int waysToStep(int n) {if (n == 1 || n == 2)return n;if (n == 3)return 4;int a = 1, b = 2, c = 4; // 分别代表 dp[i-3], dp[i-2], dp[i-1]int result = 0;for (int i = 4; i <= n; i++) {result = ((a + b) % MOD + c) % MOD;a = b;b = c;c = result;}return result;}
};

优化思路

  • 使用三个变量 abc 来存储前三个状态,减少空间复杂度。

  • 每次更新 result 后,滚动更新 abc 的值。

这样,代码的空间复杂度从 O(n) 降低到了 O(1),同时保持了时间复杂度的 O(n)

二、5. 最长回文子串 - 力扣(LeetCode)

算法代码:

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);}
};

         这段代码的目的是找到字符串 s 中的最长回文子串。它使用了中心扩展算法,通过枚举每个可能的中心点,向左右扩展,找到最长的回文子串。以下是代码的详细思路:


1. 中心扩展算法的核心思想

  • 回文串可以分为两种:

    • 奇数长度:中心是一个字符(例如 "aba")。

    • 偶数长度:中心是两个字符(例如 "abba")。

  • 通过枚举每个可能的中心点,向左右扩展,找到以该中心点为基准的最长回文子串。


2. 代码实现思路

变量说明

  • begin:记录最长回文子串的起始位置。

  • len:记录最长回文子串的长度。

  • n:字符串 s 的长度。

步骤

  1. 枚举所有可能的中心点

    • 遍历字符串 s,每个字符 s[i] 都可能是回文串的中心点。

  2. 奇数长度的扩展

    • 初始化 left 和 right 为当前中心点 i

    • 向左右扩展,检查 s[left] 和 s[right] 是否相等。

    • 如果相等,继续扩展;否则停止。

    • 计算当前回文子串的长度 right - left - 1,如果比 len 大,则更新 begin 和 len

  3. 偶数长度的扩展

    • 初始化 left 为 iright 为 i + 1(表示中心是两个字符)。

    • 向左右扩展,检查 s[left] 和 s[right] 是否相等。

    • 如果相等,继续扩展;否则停止。

    • 计算当前回文子串的长度 right - left - 1,如果比 len 大,则更新 begin 和 len

  4. 返回结果

    • 使用 s.substr(begin, len) 截取最长回文子串并返回。


3. 代码优化

  • 时间复杂度O(n^2),其中 n 是字符串的长度。每个中心点最多扩展 n 次。

  • 空间复杂度O(1),只使用了常数级别的额外空间。


4. 优化后的代码

class Solution {
public:string longestPalindrome(string s) {int begin = 0, len = 0, n = s.size();for (int i = 0; i < n; i++) {// 奇数长度扩展int l = i, r = i;expandAroundCenter(s, l, r, begin, len);// 偶数长度扩展l = i, r = i + 1;expandAroundCenter(s, l, r, begin, len);}return s.substr(begin, len);}private:void expandAroundCenter(const string& s, int l, int r, int& begin, int& len) {while (l >= 0 && r < s.size() && s[l] == s[r]) {l--;r++;}int currentLen = r - l - 1;if (currentLen > len) {begin = l + 1;len = currentLen;}}
};

5. 优化思路

  • 将奇数长度和偶数长度的扩展逻辑提取到一个单独的函数 expandAroundCenter 中,避免代码重复。

  • 通过传递 begin 和 len 的引用,直接更新最长回文子串的起始位置和长度。


6. 示例运行

输入:

string s = "babad";
Solution sol;
cout << sol.longestPalindrome(s); // 输出 "bab" 或 "aba"

运行过程:

  1. 枚举中心点 i

    • i = 0:奇数扩展得到 "b",偶数扩展得到 ""

    • i = 1:奇数扩展得到 "bab",偶数扩展得到 ""

    • i = 2:奇数扩展得到 "aba",偶数扩展得到 ""

    • i = 3:奇数扩展得到 "a",偶数扩展得到 ""

    • i = 4:奇数扩展得到 "d",偶数扩展得到 ""

  2. 最终最长回文子串为 "bab" 或 "aba"


7. 总结

  • 中心扩展算法是一种直观且高效的方法,适用于解决最长回文子串问题。

  • 通过优化代码结构,可以提高代码的可读性和可维护性。

版权声明:

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

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