• 每天都要学算法——day1


    1.组合总和(力扣第39题):

    给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

    candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 

    对于给定的输入,保证和为 target 的不同组合数少于 150 个。

     这个题我们使用的是递归,再写一个backgoing函数去递归,每次更改总和,小于target继续递归,等于时退出递归。

    1. class Solution {
    2. public:
    3. vectorint>> combinationSum(vector<int>& candidates, int target) {
    4. vectorint>>res;
    5. vector<int>tmp;
    6. sort(candidates.begin(),candidates.end());
    7. backgoing(res,candidates,tmp,target,0,0);
    8. return res;
    9. }
    10. void backgoing(vectorint>>&res,vector<int>&candidates,vector<int>&tmp,int target,int begin,int sum)
    11. {
    12. if(sum==target)
    13. {
    14. res.push_back(tmp);//等于时,把当前用于统计的tmp插入res
    15. }
    16. else
    17. {
    18. for(int i=begin;isize();++i)//从传入的begin开始遍历,当sum+candidates[i]小于target时,继续递归。
    19. {
    20. if(sum+candidates[i]<=target)
    21. {
    22. tmp.push_back(candidates[i]);
    23. backgoing(res,candidates,tmp,target,i,sum+candidates[i]);
    24. tmp.pop_back();
    25. }
    26. else{
    27. break;
    28. }
    29. }
    30. }
    31. }
    32. };

    2.最长回文子串(力扣第五题):

    给你一个字符串 s,找到 s 中最长的回文子串。

     这个题我一看到时候就是暴力解法,两层for循环,遍历区间起始位置和终止位置,然后判断这个区间是不是回文。

    但是这个题也是经典的动态规划题,一些回文串,公共子序列,递增子序列这些都是动态规划问题。

    1.首先动态规划问题要先知道dp代表什么,本体bp为布尔类型的dp[i][j]:表示区间范围[i,j] 的子串是否是回文子串,如果是dp[i][j]为true,否则为false。

    2.整体上是两种,就是s[i]与s[j]相等,s[i]与s[j]不相等这两种。    

     当s[i]与s[j]不相等,那没啥好说的了,dp[i][j]一定是false。

     当s[i]与s[j]相等时,这就复杂一些了,有如下三种情况

             情况一:下标i 与 j相同,同一个字符例如a,当然是回文子串

             情况二:下标i 与 j相差为1,例如aa,也是文子串

             情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看            i 到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-             1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。

    3.回文子串可能是从字符串s中截取,所以要确定边界。

            

    1. class Solution {
    2. public:
    3. string longestPalindrome(string s)
    4. {
    5. vectorint>>dp(s.size(),(vector<int>(s.size(),0)));
    6. int maxl=0;
    7. int left=0,right=0;
    8. for(int i=s.size()-1;i>=0;i--)
    9. {
    10. for(int j=i;jsize();j++)
    11. {
    12. if(s[i]==s[j])//情况1和2
    13. {
    14. if(j-i<=1)
    15. {
    16. dp[i][j]=true;
    17. }
    18. else if(dp[i+1][j-1])
    19. {
    20. dp[i][j]=true;
    21. }
    22. }
    23. if(dp[i][j]&&j-i+1>maxl)//确定边界
    24. {
    25. maxl=j-i+1;
    26. left=i;
    27. right=j;
    28. }
    29. }
    30. }
    31. return s.substr(left,right-left+1);
    32. }
    33. };

     

  • 相关阅读:
    一文详解IP地址编码定义、分类、范围、类型
    【设计模式】第4节:创建型模式之“单例模式”
    Java PrintStream.println方法具有什么功能呢?
    合肥大厂校招
    Linux如何设置开机自启
    mysql笔记:10. 日志
    【Java】面向过程和面向对象思想||对象和类
    【微服务】spring 控制bean加载顺序使用详解
    [linux] ModuleNotFoundError: No module named ‘torch.utils._pytree‘ 报错怎么解决
    OpenCV_CUDA_VS编译安装
  • 原文地址:https://blog.csdn.net/weixin_57133901/article/details/126187487