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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> wy的leetcode刷题记录_Day28_动态规划完结篇 -> 正文阅读

[数据结构与算法]wy的leetcode刷题记录_Day28_动态规划完结篇

wy的leetcode刷题记录_Day28_动态规划完结篇

时间:2022-10-30

784. 字母大小写全排列

今天的每日一题是:784. 字母大小写全排列

题目介绍

  1. 给定一个字符串 s ,通过将字符串 s 中的每个字母转变大小写,我们可以获得一个新的字符串。
  2. 返回 所有可能得到的字符串集合 。以 任意顺序 返回输出。

示例 1:
输入:s = “a1b2”
输出:[“a1b2”, “a1B2”, “A1b2”, “A1B2”]

示例 2:
输入: s = “3z4”
输出: [“3z4”,“3Z4”]

思路

首先对于大小写的转换,我们可以通过位运算来操作因为每个字符的大小转换相差32,我们可以通过异或32来转换,而对于搜索的话我们可以采用BFS或者DFS,这里我们采用BFS来操作:我们遍历每一个字符c:

  • 如果c为一个数字,则队列中的所有序列的末尾都加上一个c,修改后的序列放入队列
  • 如果c是一个字母,则所有的序列末尾分别加上c的小写形式和大写形式后,再放入队列
  • 如果队列中的字符长度等与s的长度,则表示搜索已经完成了

代码

class Solution {
public:
    vector<string> letterCasePermutation(string s) {
        vector<string> ans;
        queue<string> qu;
        qu.emplace("");
        while (!qu.empty()) {
            string &curr = qu.front();
            if (curr.size() == s.size()) {
                ans.emplace_back(curr);
                qu.pop();
            } else {
                int pos = curr.size();
                if (isalpha(s[pos])) {
                    string next = curr;
                    next.push_back(s[pos] ^ 32);//增加转换后的末位数的字符
                    qu.emplace(next);//放入
                }
                curr.push_back(s[pos]);                
            }
        }
        return ans;
    }
};

收获

使用BFS搜索s,最重要的是遍历顺序,不明白的可以打印出来看每一轮的情况,这样才能理解。

647. 回文子串

647. 回文子串

题目介绍

  1. 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。
  2. 回文字符串 是正着读和倒过来读一样的字符串。
  3. 子字符串 是字符串中的由连续字符组成的一个序列。
  4. 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 1:
输入:s = “abc”
输出:3
解释:三个回文子串: “a”, “b”, “c”

示例 2:
输入:s = “aaa”
输出:6
解释:6个回文子串: “a”, “a”, “a”, “aa”, “aa”, “aaa”

思路

方法一:动态规划

  1. 确定dp数组的含义:布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的?串是否是回??串,如果是dp[i][j]为
    true,否则为false。
  2. 确定dp数组的递推公式:首先我们通过嵌套循环来比较俩个字符是否相等,如果不相等的话那肯定不是回文字符串,如果相等的话情况还得细分,当ij时,也就是遍历到同一个字符的情况那肯定是回文字符串,如果i-j1那么就是这俩个字符相邻相等那么肯定也是回文字符串,而其他情况则取决于内层的字符串也就是dp[i+1][j-1]的情况,如果内层字符串是回文字符串那么他就是回文字符串,反之不是回文字符串
  3. 初始化:一开始所有的都初始化为false
  4. 遍历顺序:对于这道题遍历顺序是非常重要的,因为我们的dp[i][j]大概率通过dp[i+1][j-1]推出,所以我们肯定是从下到上,从左到右开始遍历,即从左下向右上递推。

方法二:双指针法
?先确定回?串,就是找中?然后想两边扩散看是不是对称的就可以了。在遍历中?点的时候,要注意中?点有两种情况。?个元素可以作为中?点,两个元素也可以作为中?点。

代码

class Solution {
public:
    int countSubstrings(string s) {
        int n=s.size();
        vector<vector<bool>> dp(n,vector<bool>(n,false));
        int result=0;
        
        for(int i=n-1;i>=0;i--)
        {
            for(int j=i;j<n;j++)
            {
                if(s[i]==s[j])
                {
                    if(j-i<=1)
                    {
                        dp[i][j]=true;
                        result++;
                    }
                    // else if(i-j==1)
                    //     dp[i][j]=true;
                    else if(dp[i+1][j-1])
                    {
                        result++;
                        dp[i][j]=true;
                    }
                }
            }
        }
        return result;
    }
};
class Solution {
public:
    int countSubstrings(string s) {
        int result = 0;
        for (int i = 0; i < s.size(); i++) {
            result += extend(s, i, i, s.size()); // 以i为中?
            result += extend(s, i, i + 1, s.size()); // 以i和i+1为中?
        }
             return result;
        }
    int extend(const string& s, int i, int j, int n) {
        int res = 0;
        while (i >= 0 && j < n && s[i] == s[j]) {
            i--;
            j++;
            res++;
            }
        return res;
    }
};

收获

这道题比较重要的就是递推的遍历顺序,对于遍历顺序我们首先需要列出相应的递推公式,然后根据公式手绘一个图看一下具体的遍历方法,首先必须得保证不能超限,其次保证不能死循环,最重要的是一定是由已知的知去推未知的值。

516. 最长回文子序列

516. 最长回文子序列

题目介绍

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。

子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。

示例 1:
输入:s = “bbbab”
输出:4
解释:一个可能的最长回文子序列为 “bbbb” 。

示例 2:
输入:s = “cbbd”
输出:2
解释:一个可能的最长回文子序列为 “bb” 。

思路

  1. 确定dp数组的含义:dp[i][j]:字符串s在[i, j]范围内最?的回??序列的?度为dp[i][j]。
  2. 确定dp数组的递推公式:如果s[i]与s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;如果s[i]与s[j]不相同,,那么分别加?s[i]、s[j]看看哪?个可以组成最?的回??序列。加?s[j]的回??序列?度为dp[i + 1][j]。加?s[i]的回??序列?度为dp[i][j - 1]。那么dp[i][j]?定是取最?的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
  3. 初始化:
  4. vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0)); for (int i = 0; i < s.size(); i++) dp[i][i] = 1;

代码

class Solution {
    public:
        int longestPalindromeSubseq(string s) {
        vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));
            for (int i = 0; i < s.size(); i++) dp[i][i] = 1;
                for (int i = s.size() - 1; i >= 0; i--) {
                    for (int j = i + 1; j < s.size(); j++) {
                        if (s[i] == s[j]) {
                            dp[i][j] = dp[i + 1][j - 1] + 2;
                        } 
                        else {
                            dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
                        }
                }
            }
        return dp[0][s.size() - 1];
    }
};

收获

动态规划是一个非常重要的知识点,关键就在于最基础的三部,以及多刷题!

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:49:39  更:2022-11-05 00:50:56 
 
开发: 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/16 1:54:20-

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