这个介绍摘自 https://blog.csdn.net/u013291076/article/details/45575967
class Solution {
public:
int countPrimes(int n)
{
int count = 0;
bool prime[n+1];
for(int i = 0; i < n; ++i)
prime[i] = true;
for(int i = 2; i <= sqrt(n); ++i) //计数过程
{ //外循环优化,因为判断一个数是否为质数只需要整除到sqrt(n),反推亦然
if(prime[i])//
{
for(int j = i * i; j < n; j += i) //每次增加的是i的倍数,这是需要划掉的。
//先将 2~n 的各个数放入表中,然后在2的上面画一个圆圈,然后划去2的其他倍数;第一个既未画圈又没有被划去的数是3,将它画圈,再划去3的其他倍数;现在既未画圈又没有被划去的第一个数 是5,将它画圈,并划去5的其他倍数……依次类推,一直到所有小于或等于 n 的各数都画了圈或划去为止。这时,表中画了圈的以及未划去的那些数正好就是小于 n 的素数。
{
prime[j] = false;
}
}
}
for (int i = 2; i < n; ++i)
{
if (prime[i]) count++;
}
return count;
}
};
如果上面的看的不明白可以使用下面的方法。
完全暴力求质数的算法
public int CountPrimes(int n)
{
int count = 0;
bool sign = true;
for (int i = 2; i < n; i++)
{
sign = true;
for (int j = 2; j < i; j++)
{
if (i % j == 0)
{
sign = false;
break;
}
}
if (sign)
count++; ;
}
return count;
}
一个数n如果不是素数那么一定存在若干因子(不少于2个),假设最小的因子是p,
那么p*p <= n
所以p < 根号n
//优化后的暴力算法
int countPrimes(int n)
{
int count = 0;
bool sign = true;
if(n>2) count++; //2是质数,并且是唯一的偶数
//优化1
for (int i = 3; i < n; i+=2) //除2外的质数,都是奇数
{
sign = true;
for (int j = 3; j*j <= i; j+=2)
//优化2 :j*j <= i 也有写成j <= sqrt(i),前面的更好
// 优化3: 因为i都是奇数,奇数%偶数一定不等于0,所以只要考虑奇数就可以了。
{
if (i % j == 0)
{
sign = false;
break;
}
}
if (sign)
count++;
}
return count;
}
647. 回文子串
难度中等263收藏分享切换为英文关注反馈
给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。
示例 1:
输入: "abc"
输出: 3
解释: 三个回文子串: "a", "b", "c".
示例 2:
输入: "aaa"
输出: 6
说明: 6个回文子串: "a", "a", "a", "aa", "aa", "aaa".
注意:
代码
char dp[1000][1000];
class Solution {
public:
int countSubstrings(string s) {
int n = s.length();
if (n == 0) {
return 0;
}
memset(dp, 0, sizeof(dp));
// 边界初始化
int i, j, off;
for (i = 0; i < n; i++) {
for (off = 0; off < 2 && i + off < n; off++) {
if (s[i] == s[i + off]) {
dp[i][i + off] = 1;
}
}
}
// 遍历填充dp数组
for (i = n - 1; i >= 0; i--) {
for (j = i + 2; j < n; j++) {
if (dp[i + 1][j - 1] == 1 && s[i] == s[j]) {
dp[i][j] = 1;
}
}
}
// 统计结果
int num = 0;
}
};
/*
dp[i][j]表示从i...j是否是一个回文串
dp[i][j] = 1; 如果dp[i + 1][j - 1] == 1 && s[i] == s[j]
dp[i][j] = 0; 其余情况
*/
动态规划法
class Solution {
public:
int countSubstrings(string s) {
int N = s.size();
if(N == 0) return 0;
int cnt = 0;
bool dp[N][N];
for(int i = 0;i < N;++i)
dp[i][i] = true;
for(int r = 1;r < N;++r)
for(int l = 0;l < r;++l){
if(s[l] == s[r] && (r-l==1 || dp[l+1][r-1])){
dp[l][r] = true;
cnt++;
}else
dp[l][r] = false;
}
return cnt+N;
}
};
class Solution {
public:
int countSubstrings(string s)
{
if(s.empty()) return 0;
int res = 0;
for(int i=0;i=0 && end