zoukankan      html  css  js  c++  java
  • leetcode之Palindrome Partitioning

    方法一:DFS递归,判断每一个是否为回文数
    1,首先要有一个判断字符串是否是回文的函数。容易实现,字符串从两边同时往中间走,看字符是否相同;
    2,深度优先搜索思想对字符串进行遍历。得到结果。例如,s = "abacd"; 需要对“a”“ad”“aba”“abac”“abacd”进行深度优先搜索。深度搜索的过程如下:先选“a”,发现“a”是回文,则深度遍历“bacd”,继续深度遍历,“b”也是回文,深度遍历“acd”,继续下去;
      同时,深度遍历“a”的同时,也需要深度遍历“ab”,“aba”,“abac”,“abacd”。发现只有“aba”是回文,所以继续深度搜索“cd”。

    1
    class Solution { 2 public: 3 vector<vector<string>> result; 4 void DFS(string str, vector<string>& curSubStrs, int start, int end) 5 { 6 if(start>end) 7 { 8 result.push_back(curSubStrs); 9 return; 10 } 11 for(int k=start;k<=end;k++) 12 { 13 string r=str.substr(start,k-start+1); 14 if(palindrom(r)) 15 { 16 curSubStrs.push_back(r); 17 DFS(str,curSubStrs,k+1,end); 18 curSubStrs.pop_back(); 19 } 20 } 21 } 22 bool palindrom(string r) 23 { 24 int n=r.size()-1; 25 int s=0; 26 while(s<n) 27 { 28 if(r[s]!=r[n]) 29 return false; 30 s++; 31 n--; 32 } 33 return true; 34 } 35 vector<vector<string>> partition(string s) { 36 int n=s.size(); 37 result.clear(); 38 if(n<0) return result; 39 vector<string> tmp; 40 DFS(s,tmp,0,n-1); 41 return result; 42 } 43 };
    方法二:也是递归,只不过是换个方式的方法
     1 //方法二,同样递归,但是只是处理小技巧上方法,其实第一次是想这么做得
     2 class Solution {
     3 public:
     4     vector<vector<string>> res;
     5     vector<vector<string>> partition(string s) {
     6      int n=s.size();
     7      vector<string> tmp;
     8      dfs(s,tmp);
     9      return res;
    10     }
    11     bool palindrom(string r)
    12     {
    13         int n=r.size()-1;
    14         int s=0;
    15         while(s<n)
    16         {
    17             if(r[s]!=r[n])
    18             return false;
    19             s++;
    20             n--;
    21         }
    22         return true;
    23     }
    24     void dfs(string s,vector<string>&tmp)
    25     {
    26         if(s.size()<1)          //s是空串
    27         {
    28             res.push_back(tmp);
    29             return;
    30         }
    31         for(int i=0;i<s.size();i++)
    32         {
    33             string st=s.substr(0,i+1);                //i+1是长度,从0开始,长度是i+1,其实主要是递归的思想,小的递归和大的递归实际是一样的,所以做题时可以根据最大的递归来想最小的递归是否正确
    34             if(palindrom(st))
    35             {
    36                 tmp.push_back(st);
    37                 dfs(s.substr(i+1),tmp);                  //没有第一个参数时就是从i+1到组后
    38                 tmp.pop_back();
    39             }
    40 
    41         }
    42     }
    43 };

    方法三:采用动态规划的方法
    举例:aabc,这里动态规划是dict[i][j]表示从i到j是否为回文,如果i=0,j=3,就先判断s[i]是否等于s[j],如果j-i<=2,则说明i,j是连着,或一个数,或3个数,如a,ab,aab这种,
    只用判断s[i]是否等于s[j]即可,如果j-i>2则判断dict[i+1][j-1]是否为回文,所以以2维数组代表i到j,因为需要先知道后面的,所以要从后向前,又j从题意上是要大于等于i,
    所以有:
    for(int i=n-1;i>=0;i--)
    {
    fro(int j=i;j<n;j++)
    {
    ............
    }
    }
    注意substr(start,i-start+1),错了好几次,是从start开始,长度是i-start+1,用substr(start,i+1),是不行的,因为后面start会增加,只有第一个start=0是正确,后面就不对
    了如aaabc,start=2时,本来想要a,如果i+1,就成了3,从start开始长度为3就是abc了,所以应该是i-start+1为长度,是1正确.
    代码如下:
     1 //方法三,提前采用动态规划,这样可以不用后来每个都递归判断,能减少重复判断
     2 class Solution {
     3 public:
     4     vector<vector<string>> res;
     5     vector<vector<string>> partition(string s) {
     6      int n=s.size();
     7      if(n<=0) return res;
     8      
     9      vector<vector<bool>> dict(n,vector<bool>(n,false));
    10      for(int i=n-1;i>=0;i--)
    11      {
    12          for(int j=i;j<n;j++)
    13          {
    14              if(s[i]==s[j]&&(j-i<=2||dict[i+1][j-1]))
    15              {
    16                  dict[i][j]=true;
    17              }
    18          }
    19      }
    20      vector<string> tmp;
    21      dfs(s,dict,0,tmp);
    22      return res;
    23     }
    24     void dfs(string &s,vector<vector<bool>>& dict,int start,vector<string>& tmp)
    25     {
    26         if(start==s.length())
    27         {
    28             res.push_back(tmp);
    29             return;
    30         }
    31         for(int i=start;i<s.length();i++)
    32         {
    33             if(dict[start][i])
    34             {
    35                 tmp.push_back(s.substr(start,i-start+1));
    36                 dfs(s,dict,i+1,tmp);
    37                 tmp.pop_back();
    38             }
    39         }
    40     }
    41     
    42 };
  • 相关阅读:
    微信 JS SDK 的 chooseImage 接口在部分安卓机上容易造成页面刷新
    规约模式Specification Pattern
    ASP.NET Core 1.0基础之日志
    C# 7 新特性-2
    C# 7 新特性-1
    ASP.NET Core 1.0基础之诊断
    ASP.NET Core 1.0基础之依赖注入
    ASP.NET Core 1.0 基础之配置
    ASP.NET Core 1.0基础之静态文件处理
    FreeSql生产环境自动升级数据库解决方案
  • 原文地址:https://www.cnblogs.com/zmlctt/p/3704364.html
Copyright © 2011-2022 走看看