当前位置: 首页 > news >正文

代码学习总结(一)

代码学习总结(一)

这个系列的博客是记录下自己学习代码的历程,有来自平台上的,有来自笔试题回忆的,主要基于 C++ 语言,包括题目内容,代码实现,思路,并会注明题目难度,保证代码运行结果

1 最长公共前缀

简单 字典树 匹配

编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。

示例输入输出 1:
输入:strs = [“flower”,“flow”,“flight”]
输出:“fl”

示例输入输出 2:
输入:strs = [“dog”,“racecar”,“car”]
输出:“”
解释:输入不存在公共前缀。

提示:

  • 1 <= strs.length <= 200
  • 0 <= strs[i].length <= 200
  • strs[i] 如果非空,则仅由小写英文字母组成

思路解析:

  1. 把第一个字符串作为基准,然后把它和第二个进行匹配,把二者的公共前缀取出来
  2. 把基准替换为公共前缀,分别和其他的字符串进行比较,再把新的公共替换为基准
  3. 返回最终的基准
开始
strs是否为空?
返回空字符串
设置prefix为strs_0
初始化i = 1
i < strs.size?
返回prefix
初始化j = 0
j < prefix.size 且 j < strs_i.size 且 prefix_j == strs_i_j?
j加1
截断prefix: prefix = prefix.substr_0_j
prefix是否为空?
i加1

本地 debug 代码

#include <iostream>
#include <vector>
#include <string>

using namespace std;

string longestCommonPrefix(vector<string>& strs) {
    if (strs.empty()) return "";

    // 取第一个字符串作为基准
    string prefix = strs[0];

    // 从第二个字符串开始比较
    for (int i = 1; i < strs.size(); ++i) {
        int j = 0;
        // 比较当前前缀和 strs[i] 的公共部分
        while (j < prefix.size() && j < strs[i].size() && prefix[j] == strs[i][j]) {
            ++j;
        }
        // 截断前缀
        prefix = prefix.substr(0, j);
        // 如果公共前缀为空,直接返回
        if (prefix.empty()) return "";
    }

    return prefix;
}

// 测试用例
int main() {
    vector<string> strs1 = {"flower", "flow", "flight"};
    vector<string> strs2 = {"dog", "racecar", "car"};

    cout << "示例 1 输出: " << longestCommonPrefix(strs1) << endl; // 输出: "fl"
    cout << "示例 2 输出: " << longestCommonPrefix(strs2) << endl; // 输出: ""

    return 0;
}

上述代码的运行结果为

project cover 代码运行结果1

可用于提交的代码

string longestCommonPrefix(vector<string>& strs) {
    if (strs.empty()) return "";

    // 取第一个字符串作为基准
    string prefix = strs[0];

    // 从第二个字符串开始比较
    for (int i = 1; i < strs.size(); ++i) {
        int j = 0;
        // 比较当前前缀和 strs[i] 的公共部分
        while (j < prefix.size() && j < strs[i].size() && prefix[j] == strs[i][j]) {
            ++j;
        }
        // 截断前缀
        prefix = prefix.substr(0, j);
        // 如果公共前缀为空,直接返回
        if (prefix.empty()) return "";
    }

    return prefix;
}

2 单词拆分 II

中等 字典树 单词拆分

给定一个字符串 s s s 和一个字符串字典 wordDict ,在字符串 s s s 中增加空格来构建一个句子,使得句子中所有的单词都在词典中。以任意顺序 返回所有这些可能的句子。

注意:词典中的同一个单词可能在分段中被重复使用多次。

示例输入输出 1:
输入: s = “catsanddog”, wordDict = [“cat”,“cats”,“and”,“sand”,“dog”]
输出: [“cats and dog”,“cat sand dog”]

示例 2:

输入: s = “pineapplepenapple”, wordDict = [“apple”,“pen”,“applepen”,“pine”,“pineapple”]
输出: [“pine apple pen apple”,“pineapple pen apple”,“pine applepen apple”]
解释: 注意你可以重复使用字典中的单词。

示例 3:
输入: s = “catsandog”, wordDict = [“cats”,“dog”,“sand”,“and”,“cat”]
输出 :[]

思路解析:

  1. 由于需要寻找同一个字符串在某个给定字典下所有可能的单词组合,所以最好是使用递归解决
  2. 而为了方便搜索,可以将给定字典转化为无序字典,并使用一个单独的字典用来存储已经搜索出的结果
  3. 这里的递归对象因为是一个字符串,所以可以从左开始搜索,拿到第一个成型的单词后,将右侧的部分作为新的对象,进行递归,然后把左侧的单词压入结果字典中
开始
初始化字典和记忆化搜索
调用 dfs 函数
memo 中是否存在 s?
返回 memo_s
初始化结果集 result
字典中是否存在 s?
将 s 加入 result
初始化 i = 1
i < s.size?
将 result 存入 memo_s
截取 left 和 right
字典中是否存在 left?
i 加 1
递归处理 right 部分
遍历 rightPart 结果
将 left + '' + sub 加入 result
返回 result
打印结果
结束

本地 debug 代码

#include <iostream>
#include <vector>
#include <string>
#include <unordered_set>
#include <unordered_map>

using namespace std;

class Solution {
public:
    vector<string> wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> dict(wordDict.begin(), wordDict.end()); // 初始化无序集合
        unordered_map<string, vector<string>> memo; // 初始化记忆化搜索
        return dfs(s, dict, memo);
    }

private:
    vector<string> dfs(const string& s, unordered_set<string>& dict,
                       unordered_map<string, vector<string>>& memo) {
        // 因为memo 是空的,所以如果 s 存在于这个空的变量中,它也是空的
        if (memo.count(s)) return memo[s];

        // 如果整个输入都存在于字典中,那直接返回
        vector<string> result;
        if (dict.count(s)) {
            result.push_back(s);
        }

        // 针对字符串本身进行搜索
        for (int i = 1; i < s.size(); ++i) {
            string left = s.substr(0, i); // 往左搜索,字符的左侧部分
            string right = s.substr(i); // 往右搜索,字符的右侧部分

            if (dict.count(left)) { //如果左侧部分存在于字典中
                vector<string> rightPart = dfs(right, dict, memo); // 递归对右侧部分进行处理
                for (const string& sub : rightPart) {
                    result.push_back(left + " " + sub); // 将左侧部分和右侧部分都压入到结果中
                }
            }
        }

        memo[s] = result;
        return result;
    }
};

void printResults(const std::vector<std::string>& results) {
    std::cout << "[";
    for (size_t i = 0; i < results.size(); ++i) {
        std::cout << "\"" << results[i] << "\"";
        if (i != results.size() - 1) {
            std::cout << ",";
        }
    }
    std::cout << "]" << std::endl;
}

// 测试用例
int main() {
    Solution sol;

    string s1 = "catsanddog";
    vector<string> wordDict1 = {"cat","cats","and","sand","dog"};

    string s2 = "pineapplepenapple";
    vector<string> wordDict2 = {"apple","pen","applepen","pine","pineapple"};

    string s3 = "catsandog";
    vector<string> wordDict3 = {"cats","dog","sand","and","cat"};

    vector<string> results1 = sol.wordBreak(s1, wordDict1);
    printResults(results1); // 输出: ["cats and dog","cat sand dog"]

    vector<string> results2 = sol.wordBreak(s2, wordDict2);
    printResults(results2); // 输出: ["pine apple pen apple","pineapple pen apple","pine applepen apple"]

    vector<string> results3 = sol.wordBreak(s3, wordDict3);
    printResults(results3); // 输出: []

    return 0;
}

上述代码的运行结果为

project cover 代码运行结果2

可用于提交的代码

class Solution {
public:
    vector<string> wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> dict(wordDict.begin(), wordDict.end()); // 初始化无序集合
        unordered_map<string, vector<string>> memo; // 初始化记忆化搜索
        return dfs(s, dict, memo);
    }

private:
    vector<string> dfs(const string& s, unordered_set<string>& dict,
                       unordered_map<string, vector<string>>& memo) {
        // 因为memo 是空的,所以如果 s 存在于这个空的变量中,它也是空的
        if (memo.count(s)) return memo[s];

        // 如果整个输入都存在于字典中,那直接返回
        vector<string> result;
        if (dict.count(s)) {
            result.push_back(s);
        }

        // 针对字符串本身进行搜索
        for (int i = 1; i < s.size(); ++i) {
            string left = s.substr(0, i); // 往左搜索,字符的左侧部分
            string right = s.substr(i); // 往右搜索,字符的右侧部分

            if (dict.count(left)) { //如果左侧部分存在于字典中
                vector<string> rightPart = dfs(right, dict, memo); // 递归对右侧部分进行处理
                for (const string& sub : rightPart) {
                    result.push_back(left + " " + sub); // 将左侧部分和右侧部分都压入到结果中
                }
            }
        }

        memo[s] = result;
        return result;
    }
};

void printResults(const std::vector<std::string>& results) {
    std::cout << "[";
    for (size_t i = 0; i < results.size(); ++i) {
        std::cout << "\"" << results[i] << "\"";
        if (i != results.size() - 1) {
            std::cout << ",";
        }
    }
    std::cout << "]" << std::endl;
}

这里的题目是 leetcode 中的,感兴趣的同学们可以去提交下试试,可以直接运行通过,每日二题,努力加油😉!!!

相关文章:

  • 目标追踪Hyperspectral Adapter for Object Tracking based on Hyperspectral Video
  • 项目二 使用miniedit创建拓扑
  • Vue 项目中 package.json 文件的深度解析
  • 列出一个目录中所有文件的名字
  • 【问题记录】记录2个安装Centos/Anolis系统卡死在安装包阶段的问题?(硬盘分区?换设备)
  • RCE之无字母数字RCE
  • SLAM(七)-卡尔曼滤波
  • Servlet、HTTP与Spring Boot Web全面解析与整合指南
  • C++语言程序设计——01 C++程序基本结构
  • Node.js种cluster模块详解
  • IKBC F108 白色背光普通版说明书
  • 前端工程化之新晋打包工具
  • MySQL:InnoDB
  • 埃隆·马斯克如何通过开源创新塑造未来
  • 基于TCP Socket 实现心跳机制
  • 【AI提示词】API开发专家
  • Python operator 模块介绍
  • 关于 Java 预先编译(AOT)技术的详细说明,涵盖 GraalVM 的配置、Spring Boot 3.x 的集成、使用示例及优缺点对比
  • (二十)安卓开发中的事件监听(Listener)的使用方法梳理
  • 【全队项目】智能学术海报生成系统PosterGenius--多智能体辩论
  • 重庆江北区网站建设公司/河北网站seo策划
  • ps做 网站标准尺寸是多少合适/沈阳关键字优化公司
  • django 开放api 做网站/免费seo视频教学
  • 自问自答网站怎么做/哪里有专业的培训机构
  • php 企业网站cms/百度代运营公司
  • 做网站和推广工资多少/苏州关键词排名提升