【每日一题】leetcode 664.奇怪的打印机

题目描述(传送门

有台奇怪的打印机有以下两个特殊要求:

打印机每次只能打印由 同一个字符 组成的序列。
每次可以在任意起始和结束位置打印新字符,并且会覆盖掉原来已有的字符。
给你一个字符串 s ,你的任务是计算这个打印机打印它需要的最少打印次数。

示例 1:

输入:s = "aaabbb"
输出:2
解释:首先打印 "aaa" 然后打印 "bbb"

示例 2:

输入:s = "aba"
输出:2
解释:首先打印 "aaa" 然后在第二个位置打印 "b" 覆盖掉原来的字符 'a'

解题思路

首先我们来看看例子:
比如说是字符串 abab

  1. 打印字符串a的时候,只需要打印一次。
  2. 打印字符串ab的时候,需要打印两次,也就是在1的基础上在打印一次。
  3. 打印字符串aba的时候,需要打印两次,也是在1的基础上在打印一次。(两边字符相同,最后的字符也就不要单独打印一次,在打印开头的时候就直接打印出最后边的字符了,也就是先打印aaa 在打印aba)
  4. 打印字符串abab的时候,需要打印三次,(两边字符不相同就需要就行字符串的拆分,a+bab或者 ab+ab 或者 aba +b),在这里选择aba+b这种拆分方式,最终是应该打印三次。

动态规划

状态定义:dp [i] [ j] 代表的是字符串在区间【i,j】中需要的最少打印次数。
初始化;dp[i][i] =1
状态方程:

在这里插入图片描述
返回值:dp[0][n-1]

在这里插入图片描述

代码

import java.util.Arrays;

/**
 * @ClassName Main
 * @Description :TODO
 * @Author Josvin
 * @Date 2021/05/24/11:47
 */
public class Main {
    public static void main(String[] args) {
        System.out.println(strangePrinter("abcc"));
    }
    public static int strangePrinter(String s) {
        int n = s.length();
        int[][] dp = new int[n][n];
        // dp[i][j] 表示打印完成区间【i,j】的最少操作数
        for (int i = n - 1; i >= 0; i--) {
            // 初始化 dp[i][i] = 1
            dp[i][i] = 1;
            for (int j = i + 1; j < n; j++) {
                // 两边字符相等的情况
                if (s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = dp[i][j - 1];
                } else {
                    // 两边字符不相等的情况
                    int minNum = Integer.MAX_VALUE;
                  //  System.out.println("============================");
                    for (int k = i; k < j; k++) {
                        minNum = Math.min(minNum, dp[i][k] + dp[k + 1][j]);
                   //     System.out.println("[i="+i+"  k="+k  +"][k+1="+(k+1)+"  j="+j+"]");
                    }
                    dp[i][j] = minNum;
                }
                for (int m = 0; m < dp.length; m++) {
                    System.out.println(Arrays.toString(dp[m]));
                }
                System.out.println("==============");


            }
            /*for (int j = 0; j < dp.length; j++) {
                System.out.println(Arrays.toString(dp[j]));
            }*/
        }
        return dp[0][n - 1];
    }
}

看看过程:

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值