IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> C++算法集锦:动态规划(二) -> 正文阅读

[数据结构与算法]C++算法集锦:动态规划(二)

单词拆分(一)

牛客链接:NC181 单词拆分(一)
在这里插入图片描述
题解1:DFS

每次从字符串中从头开始选择定长的子字符串去集合中寻找对应目标,如果存在,则继续这么操作寻找后续字符串。如果找到最后,字符串为0了,那么说明字符串集合能够组成这个字符串。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @param dic string字符串vector 
     * @return bool布尔型
     */
    bool wordDiv(string s, vector<string>& dic) {
        // write code here
        if(s.size() == 0)
            return true;
        int ans = false;
        for(int i =0;i<=s.size();++i){   //递归查找
            string temp = s.substr(0,i);
            if(find(dic.begin(), dic.end(), temp) != dic.end())
            {
                ans = wordDiv(s.substr(i), dic);
            }
            if(ans == true)   //截枝
                break;
        }
        return ans;
    }
};

题解2:动态规划

设定一个dp数组,初始化为0。其中dp[i]=1表示以i结尾的字符串能够通过集合组合而成。 当前dp[i]可以通过前j个字符串和j-i字符串组合而成,如果dp[j]=1,且i-j的子字符串在集合中,则dp[i] =1;

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @param dic string字符串vector 
     * @return bool布尔型
     */
    bool wordDiv(string s, vector<string>& dic) {
        // write code here
        unordered_set<string> us;  //保所有出现过的字符串
        for(string sub:dic)
            us.insert(sub);
        
        bitset<501> dp = 0;   //比vector更快
        dp[0] = 1;								
        for(int i =1;i<=s.size();++i){     //遍历之后的每一位
            for(int j =0;j<i;++j){          //截取字符串长度
                if(dp[j] && us.find(s.substr(j,i-j)) != us.end()) //能表示直接退出循环。
                {
                    dp[i] = 1;
                    break;
                }
            }
        }
        return dp[s.size()];
    }
};

单词拆分(二)

牛客链接:NC182 单词拆分(二)
在这里插入图片描述
解法1:DFS

深度搜索每个可能的同时,加其加入到子答案中。当s剩余0时,子答案加入答案集合,否则不成立,他不是一个子答案。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @param dic string字符串vector 
     * @return string字符串vector
     */
    void dfs(string s, string sub_ans, vector<string>& dic, vector<string> &ans){  //dfs
        if(s.size() == 0){
            sub_ans.erase(0, 1); //去掉开头的空格
            ans.push_back(sub_ans);
            return;
        }
        for(int i = 0;i<=s.size();++i)  
        {
            if(find(dic.begin(),dic.end(),s.substr(0,i))!=dic.end())
            {
                string temp = sub_ans;
                sub_ans = sub_ans +" "+s.substr(0,i);
                dfs(s.substr(i), sub_ans, dic, ans);
                sub_ans = temp;
            }
        }
    }
    
    vector<string> wordDiv(string s, vector<string>& dic) {
        // write code here
        vector<string> ans;
        dfs(s,"",dic,ans);
        return ans;
    }
};

最长公共子数组

牛客链接:NC183 最长公共子数组
在这里插入图片描述

解法1:动态规划

定义一个二维数组ans[i][j],其中ans[i][j]表示以A中第i个元素和B中第j个元素结尾的最长后缀序列的长度,递推关系如下:
如果A[i-1] == B[j-1],则ans[i][j] = ans[i-1][j-1] + 1; 即在原有的基础后缀基础上加上延伸一个。
否则,后缀不存在,重新计算后缀,ans[i][j] = 0;

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param A int整型vector 
     * @param B int整型vector 
     * @return int整型
     */
    int longestCommonSubarry(vector<int>& A, vector<int>& B) {
        // write code here
        if(A.size() == 0 or B.size() == 0)
            return 0;
        int res = 0;
        vector<vector<int>> ans(A.size()+1,vector<int>(B.size()+1,0));
        for(int i =1;i<=A.size();++i){         
            for(int j =1;j<=B.size();++j){   
                if(A[i-1] == B[j-1])  
                    ans[i][j] = ans[i-1][j-1] + 1;         //可以优化
                else{
                    ans[i][j] = 0;
                }
                res = max(res, ans[i][j]);
            }
        }
        return res;
    }
};

这里可以通过使用一维数组滑动更新,实现空间优化。每次都要利用第j-1个信息,因此要先更新j在更新j-1。
每次更新的时候通过扫描前一个字符与当前字符是否相等,来考虑当前是否能够通过前一个最长序列来延续,以此省掉第一个维度。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param A int整型vector 
     * @param B int整型vector 
     * @return int整型
     */
    int longestCommonSubarry(vector<int>& A, vector<int>& B) {
        // write code here
        if(A.size() == 0 or B.size() == 0)
            return 0;
        int res = 0;
        vector<int> ans(B.size()+1,0);
        for(int i = 1; i<=A.size(); ++i){
            for(int j = B.size(); j>=0; --j){
                if(A[i-1] == B[j-1])
                    ans[j] = ans[j-1] + 1;
                else{
                    ans[j] = 0;
                }
                res = max(res, ans[j]);
            }
        }
        return res;
    }
};

压缩字符串(一)

牛客链接:NC101 压缩字符串(一)
在这里插入图片描述
解法1:栈

从头到尾遍历,出现不同的元素,统计栈内元素个数,为1则不需要输出,同时清空栈,用于计算下一个元素。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param param string字符串 
     * @return string字符串
     */
    string compressString(string param) {
        // write code here
        stack<char> s;
        string ans = "";
        if(param.size() == 0)
            return ans;
        for(int i =0; i<param.size();++i){
            if(s.size()==0 or param[i] == s.top())
                s.push(param[i]);
            else{
                ans+=s.top();
                if(s.size()>1)
                    ans+=to_string(s.size());
                while(s.size()>0)
                    s.pop();
                s.push(param[i]);
            }
        }
        ans+=s.top();
        if(s.size()>1)
            ans+=to_string(s.size());
        return ans;
    }
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-21 19:13:41  更:2022-05-21 19:15:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:48:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码