/*解题思路:
我们通过回文子串的定义以及例子可以知道,
当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);
}
}