sdas
sddsdsssdsas
/**
解题思路:找规律的题,首先我们要找每一位出现1的个数,然后考虑每一位'0'~'9'不同时,分别对应的1的个数的计算公式,然后遍历所有位,这道题可以看题解,讲解的很好。
我们令当前位为cur,然后低于他的位为low,高于他的位为high,dight为cur对应的10^cur
当cur==0, 1的个数为 high*dight
当cur==1, 1的个数为high*dight+low+1
当cur=2~9,1的个数为(high+1)*dight
然后初始值
high = n/10 , low =0 , cur=hig%10, dight=1
遍历所有位怎么结束的呢?当high==0,且cur==0时,则结束
递归方程:
low += cur*dight cur = hight%10 high/=10 dight *= 10
*/
class Solution {
public int countDigitOne(int n) {
//初始值
int low = 0 , cur = n%10 , high = n/10 , dight=1;
//返回值
int res=0;
//遍历位置
while(high!=0 || cur!=0){
//计算值
if(cur == 0)
res += high*dight;
else if(cur == 1)
res += high*dight+low+1;
else
res += (high+1)*dight;
//转移方程
low += cur*dight;
cur = high%10;
high /= 10;
dight *= 10;
}
return res;
}
}
/**
解题思路:第四遍了 , 动态规划dp[i][j],p的前j个字符能否匹配前i个字符
首先是边界值:dp[0][j],只有"x*x*这样的情况才为true"
接下来考虑转移方程:
1、当p.charAt(j)>='a'&&p.charAt(j)<='z',则如果p.charAt(j)==s.charAt(j),则dp[i][j] = dp[i-1][j-1];
2、当p.charAt(j) = '.' , dp[i][j] = dp[i-1][j-1]
3、当p.charAt(j) = '*' :
3.1 当*匹配0个, dp[i][j] = dp[i][j-2]
3.2 当*匹配1个(其实也对应着多个), 如果p.charAt(j-1)==s.charAt(i) dp[i][j] = dp[i-1][j]
3.3 当p.charAt(j-1) = '.' , 则dp[i][j] = dp[i-1][j]
*/
class Solution {
public boolean isMatch(String s, String p) {
int sLen = s.length();
int pLen = p.length();
//if(sLen==0 || pLen ==0) return false; //这是错的!!!比如:s="" p =".*"
boolean[][] dp = new boolean[sLen+1][pLen+1];
//边界
dp[0][0] = true;
for(int i=2 ; i<=pLen ; i++){
if(p.charAt(i-1) == '*'){
dp[0][i] = dp[0][i-2];
}
}
//转移方程
for(int i=1 ; i<=sLen ; i++){
for(int j=1 ; j<= pLen ; j++){
int sCurChar = s.charAt(i-1); //技巧,因为我们要比较大小,所以我们要将其转换成int
int pCurChar = p.charAt(j-1);
//开始判断 前两种情况可以结合起来,
if(pCurChar == '.' || sCurChar == pCurChar)
dp[i][j] = dp[i-1][j-1];
else if(pCurChar == '*'){ //然后开始判断'*'的情况
//0个的情况
if(dp[i][j-2])
dp[i][j] = dp[i][j-2];
else if(sCurChar == p.charAt(j-2) || p.charAt(j-2) == '.')
dp[i][j] = dp[i-1][j];
}
}
}
return dp[sLen][pLen];
}
}