2021-05-22 LeetCode “阿里巴巴企业题库” -------9. 回文数 1411. 给 N x 3 网格图涂色的方案数

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

/*解题思路:
我们通过回文子串的定义以及例子可以知道,
当x<0 ,返回false 
其余情况就是另外一道刚做的题了
用的是第5题的方法
时间复杂度O(n^2) ,空间复杂度O(n^2)
但是明显浪费了,所以我们要剪枝
*/
class Solution {
    public boolean isPalindrome(int x) {
        if(x < 0)
            return false;
        /*
        if(x >= 0 && x <= 9)  return true;  
        //在isHuiWenStr()中已经判断了字符长度为1,也就是当前判断
        */
        //当为两位数时,我们进一步判断
        String s = Integer.toString(x);
        //s进行回文子串判断
        return isHuiWenStr(s);
    }
    /*
        这时候s是一个正整数,我们对其判断,这时候就是动态规划了
        dp[i][j]表示字符串下标为i~j是否是回文子串
        最后返回dp[0][s.length()-1]
    */
    public boolean isHuiWenStr(String s){   
        int len = s.length();
        if(len<2)       //当字符串长度为1
            return true;
        boolean[][] dp = new boolean[len][len];
        for(int i=0 ; i<len ; i++){  //这里对应着s中的每一个字符串 即L==1
            dp[i][i] = true;
        }
        for(int L=2 ; L <= len ; L++){
            for(int i=0 ; i<len ; i++){
                int j = i + L -1 ;  //对应的右边界
                //这里注意右边界是否超出了范围
                if(j>=len)
                    break;
                //然后我对其进行判断,现在len>=2
                if(s.charAt(i)!=s.charAt(j))
                    dp[i][j] = false;
                else  //j-i == 1 说明是两位数
                    if(j-i>2)
                        dp[i][j] = dp[i+1][j-1];
                    else  // j-i=2
                        dp[i][j] = true;
            }
        }
        return dp[0][len-1];       
    }
}

//思路2:我们可以翻转这个数,但是没必要全部反转,反转一半就行,但是这时候要分奇偶数
时间复杂度O(logn) 空间复杂度O(1)
class Solution {
    public boolean isPalindrome(int x) {
        //先注意回文数的局限性,当x<0,或者x=10,20都不行,0可以
        if(x<0 || (x % 10==0 && x!=0))
            return false;
        //然后我们继续判断,不过这样判断要注意奇偶数
        int huiWenInt = 0;
        while(x > huiWenInt){
            huiWenInt = huiWenInt * 10 + x % 10;
            x/=10;
        }
        //这时候就要分奇数偶数
        return x == huiWenInt || x == huiWenInt/10;
    }
}

//思路3:粗暴解法
class Solution {
    public boolean isPalindrome(int x) {
        String reversedStr = (new StringBuilder(x + "")).reverse().toString();
        return (x + "").equals(reversedStr);
    }
}

在这里插入图片描述

/*动态规划:我们要去具体想,如何构建转移方程,我们发现每一层的颜色有两种情况,ABA ABC
我们通过dp[i][0]、dp[i][1]分别代表当前层的ABA和ABC的种数
注意:第一层一共有12个,dp[0][0] = 6 dp[0][1] =6 
比如我们用012代表三个颜色:
010、020、101、202、121、212、012、021、120、102、210、201
如果当前层为010:下一层可以 101 202 121 102 201 一共5种  ABA三种 ABC两种
当前层为ABC:012:下一层:101 121 120 201   一共5种 ABA 两种 ABC两种
因此我们写转移方程: (i>0) 
dp[i][0] = 3*dp[i-1][0] + 2*dp[i-1][1]
dp[i][1] = 2*dp[i-1][0] + 3*dp[i-1][1]
时间复杂度O(n)
空间复杂度O(n)
*/
class Solution {
    public int numOfWays(int n) {
        if(n == 1) return 12;
        final int div = 1000000007;
        long [][] dp = new long[n][2];  //注意
        dp[0][0] = 6;
        dp[0][1] = 6;
        for(int i=1 ; i < n ; i++){
            /*因为太大,一定要处理      dp[i][0] = 3*dp[i-1][0] + 2*dp[i-1][1];
            dp[i][1] = 2*dp[i-1][0] + 2*dp[i-1][1];
             */
            dp[i][0] = (3*dp[i-1][0] + 2*dp[i-1][1]) % div;
            dp[i][1] = (2*dp[i-1][0] + 2*dp[i-1][1]) % div;
        }
        return (int)((dp[n-1][0] + dp[n-1][1])%div);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值