2.18
https://leetcode-cn.com/problems/count-sorted-vowel-strings/submissions/
统计字典序元音字符串的数目
解法①
可以参考这个
https://leetcode-cn.com/problems/count-sorted-vowel-strings/solution/lie-chu-lai-fa-xian-shi-yang-hui-san-jia-66kb/
找规律
1(c44) 5(c54) 15(c64) 35(c74) 70(c84)
1(c33) 4(c43) 10(c53) 20(c63) 35(c73)
1(c22) 3(c32) 6(c42) 10(c52) 15(c62)
1(c11) 2(c21) 3(c31) 4(c41) 5(c51)
1(c00) 1(c10) 1(c20) 1(c30) 1()
class Solution { public: int countVowelStrings(int n) { long long c[60][55]; for(int i=0;i<55;i++) for(int j=0;j<=i;j++) if(!j||!i)c[i][j]=1; else c[i][j]=c[i-1][j]+c[i-1][j-1]; return c[4+n][4]; } };
解法② ←解法①普及化
组合数学
解法③dp
未优化,二维
int countVowelStrings(int n) { int dp[n+1][5]; for(int i=0;i<5;i++) dp[1][i]=1; for (int i=2;i<=n;i++) { //长度i的以u结尾的字符串可以由任意一个长度i-1的字符串结尾加个u得到 dp[i][4]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]+dp[i-1][3]+dp[i-1][4]; dp[i][3]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]+dp[i-1][3]; dp[i][2]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]; dp[i][1]=dp[i-1][0]+dp[i-1][1]; //长度i的以a结尾的字符串只能由长度i-1的以a结尾的字符串结尾加个a得到 dp[i][0]=dp[i-1][0]; } //最终答案求个和就行啦 return dp[n][0]+dp[n][1]+dp[n][2]+dp[n][3]+dp[n][4]; }
优化,一维
class Solution { public: int countVowelStrings(int n) { vector<int> count(5, 1); for (int i = 2; i <= n; i++) { for (int j = 3; j >= 0; j--) // 从倒数第二个开始算 count[j] += count[j+1]; } int ans = 0; for (auto v : count) ans += v; return ans; } };
https://leetcode-cn.com/problems/number-of-1-bits/submissions/
位1的个数
位运算:
三种操作:
第一种,遍历;
第二种将最低位的1变成0,实现 (n&n-1);
class Solution { public: int hammingWeight(unsigned n) { int ans=0; while(n) { ans++; n&=n-1; } return ans; } };
感悟:如果计算的时候发生int溢出
换用long long 或者采用unsigned(范围扩大一倍)
第三种:被称为查表
class Solution { public: int hammingWeight(unsigned n) { int table[]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4},cnt=0; while(n) { cnt+=table[n&0xf]; n>>=4; } return cnt; } };
比特位计数
https://leetcode-cn.com/problems/counting-bits/
解法①奇偶性
class Solution { public: vector<int>countBits(int num) { vector<int>result(num+1); result[0]=0; for(int i=1;i<=num;i++) { if(i&1) result[i]=result[i-1]+1; else result[i]=result[i/2]; } return result; } };
②基于上一题的解法,笨
class Solution { public: vector<int>countBits(int num) { vector<int>ans(num+1); for(int i=0;i<=num;i++) ans[i]=popcount(i); return ans; } int popcount(int i) { int cnt; for(cnt=0;i!=0;cnt++) i&=i-1; return cnt; } };
③dp+最高有效位
class Solution { public: vector<int>countBits(int num) { vector<int>ans(num+1); int i=0,b=1; while(b<=num) { while(i<b&&i+b<=num) { ans[i+b]=ans[i]+1; ++i; } i=0; b<<=1; } return ans; } };
④dp+最低有效位
vector<int>countBits(int num) { vector<int>ans(num+1); for(int i=1;i<=num;i++) ans[i]=ans[i>>1]+(i&1); return ans; }
⑤dp+设置有效位
public class Solution { public int[] countBits(int num) { int[] ans = new int[num + 1]; for (int i = 1; i <= num; ++i) ans[i] = ans[i & (i - 1)] + 1; return ans; } }