数据结构基础day9

这篇具有很好参考价值的文章主要介绍了数据结构基础day9。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目:187. 重复的DNA序列

解法1:哈希表

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        vector<string> ans;
        unordered_map<string, int> mp;
        int n=s.size(), L=10;
        for(int i=0; i<=n-L; ++i){	//从开头遍历到最后一个长度为10的子串开头
            string temp = s.substr(i,L);
            if(++mp[temp]==2){	//当数量==2时即可加入答案序列
                ans.push_back(temp);
            }
        }
        return ans;
    }
};

解法2:哈希表+滑动窗口+位运算

好长,不想看

题目:5. 最长回文子串

解法1:暴力解法

遍历每一个子串,当其是回文子串且长度最大,存储初始位置和长度。
时间复杂度O(n^3),空间复杂度O(1)

class Solution {
public:
    bool isPalindrome(string s, int left, int right){	//判断s字符串中left到right位置的子串是否为回文串
        while(left<right){
            if(s[left] != s[right]) return false;
            ++left; --right;
        }
        return true;
    }

    string longestPalindrome(string s) {
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大长度可以是一个字母
        int begin = 0;	//初始位置

        for(int i=0; i<n-1; ++i){	//遍历头,注意遍历到n-1
            for(int j=i+1; j<n; ++j){	//遍历从i开始的子串的尾,
                if(j-i+1>maxLen && isPalindrome(s, i, j)){	//当子串长度大于当前最大长度,且子串为回文串
                    maxLen = j-i+1;	//更新最大长度
                    begin = i;	//更新起始位置
                }
            }
        }

        return s.substr(begin, maxLen);	//返回s的最大长度回文子串
    }
};

解法2:动态规划

相当于在暴力解法的基础上空间换时间,时间复杂度O(n^2),空间复杂度O(n)
状态定义(定义子问题):一个字符串是否是回文串看去掉两头字符后的字符串是否是回文串,因此子问题定义为:dp[i][j]表示s[i,...,j]为回文子串
状态转移方程(描述子问题之间的联系)dp[i][j] = (s[i]==s[j]) && (dp[i+1][j-1]=true)
初始化:边界条件就是当子串长度为1的时候,显然是回文子串,比如,ij的一个子串在i和j位置的字符相同时,判断去掉ij位置字符后的子串长度是否是回文子串,一致判断到去掉ij位置字符后的子串长度小于2,即j-1-(i+1)+1<2 -> j-i<3
输出dp[i][j]表示ij的子串是否是回文子串,判断j-i+1是否大于maxLen,如果大于,记录maxLenbegin=i
优化空间:见解法3中心拓展法
PS:注意都是先确定起始位置和长度,最后再截取最长回文子串
数据结构基础day9,LeetCode,数据结构,算法,动态规划

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大回文子串长度
        int begin = 0;	//最大回文子串起始位置

        vector<vector<int>> dp(n, vector<int>(n));	//dp定义,true是非0数,false是0
        for(int i=0; i<n; ++i){	//初始定义,每个字符单独都是回文子串,对角线为true
            dp[i][i] = true;
        }
        for(int j=1; j<n; ++j){	//从左上角开始遍历,注意从1开始,先遍历列
            for(int i=0; i<j; ++i){	//后遍历行,到对角线(j)为止
                if(s[i]!=s[j]) dp[i][j]=false;	//如果i和j位置的字符不相同,则直接false
                else{	//i和j位置字符相同
                    if(j-i<3){  //边界:j-1-(i+1)+1<2 -> j-i<3
                        dp[i][j] = true;
                    }else{	//继续判断i+1到j-1的子串
                        dp[i][j] = dp[i+1][j-1];
                    }
                }
                if(dp[i][j]==true && j-i+1>maxLen){	//检查i到j子串长度是否大于maxLen
                    maxLen = j-i+1;	//更新最大回文子串长度
                    begin = i;	//更新最大回文子串初始位置
                }
            }
        }

        return s.substr(begin, maxLen);	//截取最长回文子串
    }
};

解法3:中心扩展法

时间复杂度:O(n^2),空间复杂度:O(1)
枚举中心位置的个数2(n-1),每个中心向两边扩散看是否为回文子串,偶数回文子串和奇数回文子串

class Solution {
public:
    int ExpandfromCentre(string s, int i, int j){	//从中心开始扩展,检查扩展子串是否是回文子串
        int n = s.size();
        int left = i, right = j;
        while(left>=0 && right<n){
            if(s[left]==s[right]){
                --left;
                ++right;
            }else{
                break;
            }
        }   //不符合i和j位置的字符相同时退出循环,因此返回的回文子串的长度为j-1-(i+1)+1=j-i-1,这里是left和right!!!
        return right-left-1;
    }

    string longestPalindrome(string s) {
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大回文子串长度
        int begin = 0;	//最大回文子串起始位置

        for(int i=0; i<n-1; ++i){	//枚举中心位置
            int oddLen = ExpandfromCentre(s, i, i);	//最大奇数回文子串长度
            int evenLen = ExpandfromCentre(s, i, i+1);	//最大偶数回文子串长度
            if(max(oddLen, evenLen) > maxLen){	//更新maxLen和begin
                maxLen = max(oddLen, evenLen);
                begin = i-(maxLen-1)/2;	//注意这里是推导出来的
            }
        }
        
        return s.substr(begin, maxLen);	//截取最长回文子串
    }
};

从i和maxLen倒推begin有点麻烦,可以选另一个写法:文章来源地址https://www.toymoban.com/news/detail-672305.html

class Solution {
public:
    pair<int, int> ExpandfromCentre(string s, int i, int j){	//注意函数类型是pair
        int n = s.size();
        int left = i, right = j;
        while(left>=0 && right<n){
            if(s[left]==s[right]){
                --left;
                ++right;
            }else{
                break;
            }
        }   //不符合i和j位置的字符相同时退出循环,因此返回的回文子串的长度为j-1-(i+1)+1=j-i-1,这里是left和right!!!
        return {left+1, right-1};	//注意返回值和{}
    }

    string longestPalindrome(string s) {
        int n = s.size();
        if(n<2) return s;	//特判

        int maxLen = 1;	//最大回文子串长度
        int begin = 0;	//最大回文子串起始位置

        for(int i=0; i<n-1; ++i){
            auto [odd_l, odd_r] = ExpandfromCentre(s, i, i);	//注意加[]
            auto [even_l, even_r] = ExpandfromCentre(s, i, i+1);
            if(odd_r-odd_l+1 > maxLen){
                maxLen = odd_r-odd_l+1;
                begin = odd_l;
            }
            if(even_r-even_l+1 > maxLen){
                maxLen = even_r-even_l+1;
                begin = even_l;
            }
        }
        
        return s.substr(begin, maxLen);	//截取最长回文子串
    }
};

到了这里,关于数据结构基础day9的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法分析与设计考前冲刺 (算法基础、数据结构与STL、递归和分治、 动态规划、贪心算法、 回溯算法)

    算法分析与设计考前冲刺 算法基础 算法是一系列解决问题的清晰指令,代表着用系统的方法描述解决问题的策略机制。 程序是算法用某种程序设计语言的具体的 具体实现 算法特征: 有穷性(有限步) 确定性 输入 输出 可行性(有限时间) 算法的复杂性: 时间复杂性 和空间复

    2024年02月02日
    浏览(44)
  • 算法训练day9Leetcode232用栈实现队列225用队列实现栈

    https://programmercarl.com/%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 见我的博客 https://blog.csdn.net/qq_36372352/article/details/135470438?spm=1001.2014.3001.5501 在push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些, 输出栈如果为空,就把进栈数据全部导

    2024年01月24日
    浏览(64)
  • 数据结构day08(树、算法)

    今日任务: 二叉树: 今日思维导图 链接: 快排:快速排序法(详解)_李小白~的博客-CSDN博客图画挺好啊 常见款:https://www.runoob.com/w3cnote/quick-sort.html  

    2024年02月10日
    浏览(42)
  • 数据结构与算法学习(day1)

    (1)我是一个大三的学生(准确来说应该是准大三,因为明天才报名哈哈哈)。 (2)最近就想每天闲着没事也刷些C语言习题来锻炼下编程水平,也一直在思考企业对应届大学生能力的要求,所以经常会想到关于面试的事情。由于我也没实习过,所以我对面试没有一个具象化

    2024年02月10日
    浏览(53)
  • 【算法与数据结构】112、LeetCode路径总和

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :本题通过计算根节点到叶子节点路径上节点的值之和,然后再对比目标值。利用文章【算法和数据结构】257、LeetCode二叉树的所有路径中的递归算法。 这里要注意,默认路径之和是

    2024年02月11日
    浏览(53)
  • 【算法与数据结构】343、LeetCode整数拆分

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :博主做这道题的时候一直在思考,如何找到 k k k 个正整数, k k k 究竟为多少合适。从数学的逻辑上来说,将 n n n 均分为 k k k 个数之后, k k k 个数的乘积为最大(类似于相同周长

    2024年01月17日
    浏览(52)
  • 【算法与数据结构】474、LeetCode一和零

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :本题要找strs数组的最大子集,这个子集最多含有 m m m 个0和 n n n 个1。本题也可以抽象成一个01背包的问题。其中,strs内的元素就是物品,而 m m m 和 n n n 就是背包的维度。 d p [

    2024年01月22日
    浏览(41)
  • 【算法与数据结构】494、LeetCode目标和

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :本题和这道题【算法与数据结构】1049、LeetCode 最后一块石头的重量 II类似,同样可以转换成01背包问题。下面开始论述。假设添加正号的整数子集和为 p o s i t i v e positive p os i t

    2024年01月20日
    浏览(44)
  • 【算法与数据结构】62、LeetCode不同路径

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :机器人只能向下或者向右移动,那么到达(i,j)位置的路径和(i-1,j)以及(i,j-1)有关。那么我们就得到的动态规划的表达式 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i ] [ j − 1 ] dp[i][

    2024年01月18日
    浏览(68)
  • 数据结构算法leetcode刷题练习(1)

    给定一个三角形 triangle ,找出自顶向下的最小路径和。 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标

    2023年04月24日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包