Palindrome Partitioning II

Given a string s, partition s such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

Example:

Input: "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.
 

题目理解:给定一个字符串str,将这个字符串切分成几个子串,使得每个子串都是回文,问最少切分几次

解题思路:动态规划;动态规划的实质是记录之前步骤的信息用于当前。我们用dp[i]表示0~i的子串最少切分次数。考虑递推公式,用str[i]表示str的下标为i的字符,如果str[j] = str[i] && i < j && str的i+1~j-1子串是回文,即str的i~j子串是回文,那么在str的0~i子串切分dp[i-1]+1次一定可以满足要求;因此,考虑到我们需要判断str的i+1~j-1子串是不是子串,因此我们使用一个字典,保存以j为终点的全部回文子串的起点,因为我们从j=0开始计算,因此,计算j时,以j-1为终点的全部回文子串起点已经都记录了,代码如下:

public int minCut(String s) {
        int len = s.length();
        Map<Integer, Set<Integer>> map = new HashMap<Integer, Set<Integer>>();
        int record[] = new int[len];
        Arrays.fill(record, len - 1);
        record[0] = 0;
        char[] chs = s.toCharArray();
        for(int j = 0; j < len; j++){
        	map.put(j, new HashSet<Integer>());
        	map.get(j).add(j);
        	if(j != 0)
        		record[j] = record[j - 1] + 1;
        	for(int i = 0; i < j; i++){
        		if(chs[i] == chs[j] && (i + 1 == j || map.get(j - 1).contains(i + 1))){
        			map.get(j).add(i);
        			if(i != 0)
        				record[j] = Math.min(record[j], record[i - 1] + 1);
        			else
        				record[j] = 0;
        		}
        	}
        	//System.out.println(j + " " + map.get(j).toString());
        }
        return record[len - 1];
    }

进一步思考,在计算dp[j]时,其实我们并不需要0~j-1之间全部回文子串信息,我们需要的只是以j-1为终点的回文子串信息,因此考虑用两个bool数组记录回文子串信息

    public int minCut(String s) {
        int len = s.length();
        boolean[] cur = new boolean[len], next;
        int record[] = new int[len];
        Arrays.fill(record, len - 1);
        record[0] = 0;
        char[] chs = s.toCharArray();
        for(int j = 0; j < len; j++){
        	next = new boolean[len];
        	next[j] = true;
        	if(j != 0)
        		record[j] = record[j - 1] + 1;
        	for(int i = 0; i < j; i++){
        		if(chs[i] == chs[j] && (i + 1 == j || cur[i + 1])){
        			next[i] = true;;
        			if(i != 0)
        				record[j] = Math.min(record[j], record[i - 1] + 1);
        			else
        				record[j] = 0;
        		}
        	}
        	cur = next;
        }
        return record[len - 1];
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值