Given an integer M. return all prime numbers smaller than M.
Give a algorithm as good as you can. Need to consider time and space complexity.
The Sieve of Eratosthenes is a good place to start.
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
A couple of additional performance hints:
You only need to test up to the square root of M, since every composite number has at least one prime factor less than or equal to its square root
You can cache known primes as you generate them and test subsequent numbers against only the numbers in this list (instead of every number below sqrt(M))
You can obviously skip even numbers (except for 2, of course)
The usual answer is to implement the Sieve of Eratosthenes, but this is really only a solution for finding the list of all prime numbers smaller than N. If you want primality tests for specific numbers, there are better choices for large numbers.
Sieve of Eratosthenes is good.
i'm a novice programmer in c# (and new to S.O.), so this may be a bit verbose. nevertheless, i've tested this, and i works.
this is what i've come up with:
for (int i = 2; i <= n; i++)
{
while (n % i == 0)
{
Console.WriteLine(i.ToString());
n /= i;
}
}
Console.ReadLine();
π(n) count the primes less than or equal to n. Pafnuty Chebyshev has shown that if
limn→∞ π(n)/(n/ln(n))
exists, it is 1. There are a lot of values that are approximately equal to π(n) actually, as shown in the table.
It gives right number of prime number for this number format.I hope this will be helpful.
You can do it using a bottom up dynamic programming approach called the Sieve of Eratosthenes
Basically you create a boolean cache of all numbers upto n and you mark each the multiples of each number as not_prime.
Further optimizations can be gained by checking only upto sqrt(n) since any composite number will have at least one divisor less that sqrt(n)
public int countPrimes(int n) {
if(n==0){
return 0;
}else{
boolean[] isPrime=new boolean[n];
for(int i=2;i<n;i++){
isPrime[i]=true;
}
/* Using i*i<n instead of i<Math.sqrt(n)
to avoid the exepnsive sqrt operation */
for(int i=2;i*i<n;i++){
if(!isPrime[i]){
continue;
}
for(int j=i*i;j<n;j+=i){
isPrime[j]=false;
}
}
int counter=0;
for(int i=2;i<n;i++){
if(isPrime[i]){
counter++;
}
}
return counter;
}
}
This is what I developed for Seive of Eratosthenes. There would be better implementations,of course.
//finds number of prime numbers less than length
private static int findNumberOfPrimes(int length) {
int numberOfPrimes = 1;
if (length == 2) {
return 1;
}
int[] arr = new int[length];
//creating an array of numbers less than 'length'
for (int i = 0; i < arr.length; i++) {
arr[i] = i + 1;
}
//starting with first prime number 2, all the numbers divisible by 2(and upcoming) is replaced with -1
for (int i = 2; i < arr.length && arr[i] != -1; i++) {
for (int j = i; j < arr.length; j++) {
if (arr[j] % arr[i] == 0) {
arr[j] = -1;
numberOfPrimes += 1;
}
}
}
return numberOfPrimes;
}
The Sieve of Atkin is also the best algorithm to implement in this case and it takes only O(N) operations and O(N) space. Please refer https://en.wikipedia.org/wiki/Sieve_of_Atkin for detailed explanation of the algorithm and pseudocode.
Related
Why is KMP O(n + m)?
I know this question has probably been asked a million times on here but I haven't find a solution that convinced me/I understood or a question that matched my example.
/**
* KMP algorithm of pattern matching.
*/
public boolean KMP(char []text, char []pattern){
int lps[] = computeTemporaryArray(pattern);
int i=0;
int j=0;
while(i < text.length && j < pattern.length){
if(text[i] == pattern[j]){
i++;
j++;
}else{
if(j!=0){
j = lps[j-1];
}else{
i++;
}
}
}
if(j == pattern.length){
return true;
}
return false;
}
n = size of text
m = size of pattern
I know why its + m, thats the runtime it takes to create the lsp array to do lookups. I'm not sure why the code I passed above is O(n).
I see that above "i" always progresses forwards EXCEPT when it doesn't match and j!= 0. In that case, we can do iterations of the while loop where i doesn't move forward, so its not exactly O(n)
If the lps array is incrementing like [1,2,3,4,5,6,0]. If we fail to match at index 6, j gets updated to 5, and then 4, and then 3.... and etc and we effectively go through m extra iterations (assuming all mismatch). This can occur at every step.
so it would look like
for (int i = 0; i < n; i++) {
for (int j = i; j >=0; j--) {
}
}
and to put all the possible i j combinations aka states would require a nm array so wouldn't the runtime be O(nm).
So is my reading of the code wrong, or the runtime analysis of the for loop wrong, or my example is impossible?
Actually, now that I think about it. It is O(n+m). Just visualized it as two windows shifting.
Here is the happy number question in leetcode
This is one of the solution
Using Floyd Cycle detection algorithm.
int digitSquareSum(int n) {
int sum = 0, tmp;
while (n) {
tmp = n % 10;
sum += tmp * tmp;
n /= 10;
}
return sum;
}
bool isHappy(int n) {
int slow, fast;
slow = fast = n;
do {
slow = digitSquareSum(slow);
fast = digitSquareSum(fast);
fast = digitSquareSum(fast);
} while(slow != fast);
if (slow == 1) return 1;
else return 0;
}
Is there a chance to have infinite loop?
There would only be an infinite loop if iterating digitSquareSum could grow without bounds. But when it is called with an n digit number the result is always smaller than 100n so this does not happen because for n >= 4 the result is always smaller than the number used as input.
All that ignores that integers in the computer in most languages cannot be arbitrarily large, you would get an integer overflow if the result could grow mathematically to infinity. The result would then be likely wrong but there would still not be an infinite loop.
Let's suppose n is an integer around 250000. Using Java, I need to find the greatest prime number that ends with 7 and belongs to {1, ..., n}. Also, I need to keep an eye on computational complexity and try to lower it as much as I can.
So I was thinking of using Sieve of Eratosthenes for n, and then just checking my array of bool values
int start = (n % 10 < 7 ? n - (n % 10 + 3) : n - (n % 10 - 7) )
for (int i = start; i >= 0; i-= 10){
if(primes[i])
return i;
}
It would keep the whole thing simple i guess, but I was wondering what would be the more efficient approach be. Unless there is a way to easily avoid having an array, but I couldn't think of any.
Below here, you will find my implementation of Sieve of Eratosthenes algorithm for finding prime numbers between 1 and 250000 and also how I make use of it, to filter out all the prime number ending in 7.
The overall time complexity of this algorithm is O(N) because all the implementation is done in sieve algo.
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
int N = 250000;
ArrayList<Integer> primeWithEnding7 = new ArrayList<Integer>();
int maxPrimeNum7 = 0;
boolean[] isPrime = new boolean[N + 1];
for (int i = 2; i <= N; i++) {
isPrime[i] = false;
}
for (int i = 2; i <= N; i++) {
if (!isPrime[i]) {
int rem = i%10;
if(rem == 7) {
maxPrimeNum7 = Math.max(maxPrimeNum7, i);
primeWithEnding7.add(i);
}
for (int j = i+i; j <= N; j+=i) {
isPrime[j] = true;
}
}
}
// Print all the prime numbers ending in 7
for(int i: primeWithEnding7) {
System.out.print(i + " ");
}
System.out.println();
System.out.println("Max number is " + maxPrimeNum7);
}
}
Now let's take an example to understand why this algorithm will work for us.
So let's suppose N = 30. Now when the loop starts from 2, if 7 was not prime it would have been covered as non-prime in the inner loop j, the fact that i reaches to 7 proves that it's a prime number, So I keep a global array list as my data structure to add only those prime numbers that end in 7 and because I use % operator to calculate the last digit of the number, the time complexity of that step is O(1), so total time complexity of the algorithm comes to O(N).
Let me know, if I have made any mistake in the algorithm, I will fix it.
Hope this helps!
For EX: A sequence is giving 1 3 2 4 now i have to find the number of increasing sequences.
I came to know about BIT algorithm which is give me O(nlog2n) solution as compared to O(n2).
Code is as follow
void update(int idx ,int val){
while (idx <= MaxVal){
tree[idx] += val;
idx += (idx & -idx);
}
}
To read
int read(int idx){
int sum = 0;
while (idx > 0){
sum += tree[idx];
idx -= (idx & -idx);
}
return sum;
}
I can't understand how they are using BIT algorithms can you please help me
Binary indexed tree's read function will return the number of values which is equals or less than idx.
So, by insert each element one by one, from 0 to n (n is number of elements)
For each element, we need to know how many values that are less than this current element, and has already added to the BIT. Assume that this number is x, so the number of increasing sequence that end at this element is 2^x
After calculating all sequences that ended at this element, we need to add this element into BIT
Pseudo code:
long result = 0;
BIT tree = //initialize BIT tree
for(int i = 0; i < n; i++){
int number = tree.read(data[i] - 1);// Get the number of element that less than data[i];
result += 1L<< number;
tree.update(data[i], 1);
}
As update and read function has O(log n) time complexity, the above algo has time complexity O(n log n)
I had this question:
Given an unsorted array of positive integers and an integer N, return N if N existed in the array or the first number that is smaller than N.
in an interview and wanted to know what would be the best efficient algorithm to solve it?
I had given two approaches using hash and sorting array but it was not correct and efficient approach. I would really appreciate if someone can give an optimal algorithm for this problem.
I'm assuming this is in a C-style language; if not, please update the question to reflect the language.
If the array isn't sorted, then you have no choice but a (potentially) full traversal of the array to look for N, as any sorting operation is going take longer than simply traversing the array (other than by finding the element by "blind luck"). Something akin to this would probably be the most efficient (unless I'm missing something)
int retVal = -1;
for(int i = 0; i < ARRAY_LENGTH; i++)
{
if(array[i] == N) return N;
if(retVal == -1 && array[i] < N) retVal = array[i];
}
return retVal;
As suggested elsewhere, you can modify
if(retVal == -1 && array[i] < N) retVal = array[i];
to
if(retVal < array[i] && array[i] < N) retVal = array[i];
In order to get the largest value that's smaller than N, rather than simply the first.
Scan through the list from beginning to end, if you see a value less than N, hold on to the first one until you reach the end, or find N. If you find N, return it, if you reach the end, return the value you've held on to. Presumably there'd have to be some value to return if all the values were greater than N, but the problem doesn't state that.
O(N) performance, O(1) space usage.
It's a little trickier if you're looking for the largest value smaller than N. In which case, instead of holding on to the first value smaller than N, you simply grab a new value every time you find a value smaller than N, but larger than the value you are currently holding on to.
Simply replace
if(array[i] < N && retVal == -1) retVal = array[i];
with
if(array[i] < N && retVal < array[i]) retVal = array[i];
in Adam's answer
Here is my code:
int getNindex(int a[],int n,int N)
{
int min=-99999,i=0,minindex=-1;
for(i=0;i<n;i++)
{
if(a[i]>min && a[i]<=N)
{
min=a[i];
minindex=i;
}
}
return minindex;
}
int main()
{
int a[]={5,75,20,50,100};
int Nindex=getNindex(a,5,60);
if(Nindex>=0)
printf("index= %d,N= %d\n",Nindex,a[Nindex]);
return 0;
}