DFS——palindrome-partitioning

题目:

给定一个字符串,将字符串分成多个部分,满足每一部分都是回文串,请输出所有可能的情况。


     深搜即可。  

import java.util.*;
public class Solution {
    public ArrayList<ArrayList<String>> partition(String s) {
        ArrayList<ArrayList<String>> array=new ArrayList();
        if(s == null||s.length() == 0){
            return array;
        }
        ArrayList<String> list=new ArrayList();
        dfs(s,list,array);
        return array;
    }
    public void dfs(String s,ArrayList<String> list,ArrayList<ArrayList<String>> array){
        if(s.equals("")){
            array.add(new ArrayList(list));
            return;
        }
        for(int i=1;i<=s.length();i++){
            if(is_palindrome(s.substring(0,i))){
                list.add(s.substring(0,i));
                dfs(s.substring(i),list,array);
                list.remove(list.size()-1);
            }
        }
    }
    public boolean is_palindrome(String s){
        if(s.length() < 2){
            return true;
        }
        int left=0;
        int right=s.length()-1;
        while(left < right){
            if(s.charAt(left)!=s.charAt(right)){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}

        1.判断子串是否为回文串;2.然后深搜遍历所有的划分。

        判断子串是否为回文串采用了最朴素的循环遍历,在该题通过了测试700ms。深搜函数最重要的参数是第一个i,用来表示从字符串的i位置开始求划分,如果i已经超过了字符串的长度就说明完成了划分,保存一个可能的结果。如果i没有到字符串末尾,则判断从i开始到哪些位置是回文串,保存该回文串,然后从下一个位置继续深搜。如此就可以获得所有的划分。


关于palindrome-partitioning II的深搜问题

该问题一开始的思路肯定是直接照搬问题I的方法,采用DFS去求解。如果我们按照这个思路去实现,提交的时候会发现算法超时,即使进行了一系列的调优也不行。下面是采用DFS的最原始代码:

void dfs(int i,int parts,int len,int[][] dp)  
{  
        if(i==len)  
        {  
            if(parts<minParts)  
            {  
                minParts=parts;  
            }  
            return;  
        }  
        for(int j=i;j<len;j++)  
        {  
            if(dp[i][j]==1)  
            {  
                dfs(j+1,parts+1,len,dp);  
            }  
        }  
}  
代码是一个典型的深搜,符合深搜的基本框架,但是当输入字符串是“ ababababababababababababcbabababababababababababa ”,算法超时。实际上这个字符串还是很短的,超时说明算法复杂度太高,或者可能需要对解空间进行剪枝,这就启发我首先试试剪枝是否有效。最容易想到的剪枝策略是:如果当前的分割的个数已经大于当前最优解,则我们停止对该路径的深搜,需要的修改是对深搜的判断条件进行修改,但还是超时了,修改之后为:

void dfs(int i,int parts,int len,int[][] dp)  
    {  
        if(i==len)  
        {  
            if(parts<minParts)  
            {  
                minParts=parts;  
            }  
            return;  
        }     
        for(int j=i;j<len;j++)  
        {  
            if(dp[i][j]==1&&parts<minParts)  
            {  
                dfs(j+1,parts+1,len,dp);  
            }  
        }  
}  




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值