I was solving a leetcode question Add to Array-Form of Integer, the question is to add a vector with an integer, for example
Input: num = [2,1,5], k = 806
Output: [1,0,2,1]
Explanation: 215 + 806 = 1021
to solve this I have used two approaches, in place addition in the same vector
vector<int> _addToArrayForm(vector<int> A, int K) {
for (int i = A.size() - 1; i >= 0 && K > 0; --i) {
A[i] += K;
K = A[i] / 10;
A[i] %= 10;
}
while (K > 0) {
A.insert(A.begin(), K % 10);
K /= 10;
}
return A;
}
using forward_list
forward_list<int> addToArrayForm(vector<int>& num, int k) {
forward_list<int> res;
for(int i = num.size() -1; i >= 0; i--)
{
res.push_front((num[i] + k) % 10);
k = (num[i] + k) / 10;
}
while(k)
{
res.push_front(k % 10);
k /= 10;
}
return res;
}
I think using forward_list is better as the time complexity of push_front is O(1) while for A.insert(A.begin(), K % 10) time complexity is O(n) but on benchmarking both functions, the time taken by the vector approach is much lesser than forward_list on 10000 elements
forward_list took 0.000185 seconds
vector took 0.000019 seconds
I tried to calculate execution time, using this code
vector<int> num;
for(int i = 0; i < 10000; i++)
{
num.push_back(rand() % 10);
}
int k = 3432423;
clock_t start = clock();
forward_list<int> res = s.addToArrayForm(num, k);
clock_t end = clock();
printf("Took %f seconds\n", (((float)(end-start) / CLOCKS_PER_SEC)));
start = clock();
vector<int> res1 = s._addToArrayForm(num, k);
end = clock();
printf("Took %f seconds\n", (((float)(end-start) / CLOCKS_PER_SEC)));
Related
int main() {
int naturalNumber = 2;
int divider = 0;
int rest = 1;
long long int sumOfPrimes = 0;
while (naturalNumber <= 2000000) {
divider = naturalNumber;
while (rest != 0) {
divider--;
rest = naturalNumber % divider;
}
rest = 1;
if (divider == 1) {
sumOfPrimes = sumOfPrimes + naturalNumber;
}
naturalNumber++;
}
std::cout << sumOfPrimes;
}
Howcome does the sum output not appear on the Console after I set the loop condition to go through 2million iterations. And I don't get any error message. It works when it's set to less than ~100'000 iterations. Is this a memory issue or something else?
I was trying to calculate a sum of all primenumbers below 2 million through iteration.
This is a very inefficient way to calculate a series of prime numbers, so the most likely answer is that it's just taking a very very long time.
If you know you need all of the primes up to 2,000,000, the Sieve of Eratosthenes is your friend.
Something like:
int n = 2000000;
std::vector<bool> is_prime(n+1, true);
is_prime[0] = is_prime[1] = false;
for (int i = 2; i <= n; i++) {
if (is_prime[i] && (long long)i * i <= n) {
for (int j = i * i; j <= n; j += i)
is_prime[j] = false;
}
}
long long int sum_primes = 0;
for (int i = 0; i < n; i++) {
if (is_prime[i]) sum_primes += i;
}
This runs in O(n) complexity, vs. O(n^2).
I'm practicing myself by doing some leetcode questions, however, I don't know why that's an overflow problem right here. I knew the way I sum the subarray was terrible, any tips for the sum of the subarray?
and the run time for this code would be forever
#include <numeric>
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int size = arr.size();//5
int ans = 0;
int sumAll = 0;
int start = 3;
int tempsum;
for(int i =0; i< size; i++){ //sumitself
sumAll += arr[i];
}
ans = sumAll; //alreayd have the 1 index
if(size%2 == 0){//even number 6
int temp = size-1; //5
if(size == 2)
ans = sumAll;
else{
while(start <= temp){//3 < 5
for(int i = 0; i< size; i++){
for(int k =0; k< start; k++){//3
tempsum += arr[i+k];
if(i+k > temp) //reach 5
break;
}
}
start+=2;
}
}
ans+= tempsum;
}
else{//odd number
if(size == 1)
ans = sumAll;
else{
while(start < size){//3
for(int i = 0; i< size; i++){
for(int k =0; k< start; k++){//3
tempsum += arr[i+k];
if(i+k > size) //reach 5
break;
}
}
start+=2;
}
ans+= tempsum;
ans+= sumAll; //size index
}
}
return ans;
}
};
The problem is with arr[i+k]. The result of i + k can be equal to, or larger, than size. You check it after you have already gone out of bounds.
You should probably modify the inner loop condition so that never happens:
for(int k =0; k < start && (i + k) < size; k++){//3
Now you don't even need the inner check.
You can use prefix sum array technique and then for each index you can calculate the sub-array sum for each odd-length array using prefix sum array. I submitted the below solution in LeetCode and it beats runtime of 100% of submissions and memory usage of 56.95%
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int n = arr.size();
vector<int> prefix(n+1,0);
int sum = 0;
prefix[1] = arr[0];
for(int i=1;i<n;i++)
prefix[i+1]=(arr[i]+prefix[i]);
for(int i=0;i<n;i++)
{
for(int j=i;j<n;j+=2)
sum+=prefix[j+1]-prefix[i];
}
return sum;
}
};
https://leetcode.com/problems/sum-of-all-odd-length-subarrays/discuss/1263893/Java-100-one-pass-O(n)-with-explanation
class Solution {
public int sumOddLengthSubarrays(int[] arr) {
// alt solution: O(n)
//for each i:
// if(n -1 - i) is odd, then arr[i] is counted (n-1-i)/2 + 1 times, each from 0 to i, total ((n-i)/2+1)*(i+1) times
// if(n -1 - i) is even, then arr[i] is counted (n-1-i)/2 + 1 times, if starting subseq index diff with i is even;
// (n-1-i)/2 times, if starting index diff with i s odd, total (n-i)/2 *(i+1) + (i+1)/2
// if i is even i - 1, i - 3, .. 1, total (i -2)/2 + 1 = i / 2 = (i+1) / 2
// if i is odd i-1, i-3, .., 0 total (i-1)/2 + 1 = (i+1) / 2
int total = 0;
int n = arr.length;
for(int i = 0; i < n; i++)
total += (((n - 1 - i) / 2 + 1) * (i + 1) - ((n-i) % 2)*((i+1) / 2)) * arr[i];
return total;
}
}
This is the code for function f(T,k) where
f(T,0)=∑(from i=1 to i≤len(T)) T[i], where len(T) is length of array T.
f(T,k)=∑(from i=1 to i≤len(T)) ∑(from j=i to j≤len(T)) f(T[i...j],k-1), for k>0, where len(T) is length
of array T and T[i...j] is sub-array of T with elements form the i-th to the j-th position (T[i],T[i+1],...,T[j])
It is a recursive function and I need to reduce the complexity, but I don't know how.
Can someone help me out?
This is the problem text:
1000000007 players participate in this game and the winner is decided by random selection. To make the selection random, the company has set strict rules for selecting that player. First they number the players with identification numbers from 0 to 1000000006. Then they choose array A with N elements and the number k. They then define the winner as the player who has the identification number f (A, k) mod (100000007)
#include <iostream>
#include <vector>
using namespace std;
int N,k,a;
vector<int>A;
int fja(vector<int>A,int k){
long long suma=0;
if(k==0){// If k==0 calculate the first said function
for(auto it=A.begin();it!=A.end();it++)suma=(suma+(*it))%(1000000007);//Moduo is there because suma is very big
return suma;
}else{//If k>0 calculate the second function
int duzina=A.size();//duzina is length of A (T)
for(int i=0;i<duzina;i++){//Going through the first and second sum of second function
for(int j=i;j<duzina;j++){
vector<int>b(A.begin()+i,A.begin()+j+1);//Creating new vector (array) to pass it into the new function call
suma=(suma+fja(b,k-1))%(1000000007);//Moduo is there because suma is very big
}
}
return suma;
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin>>N>>k; //Number of elements and k
for(int i=0;i<N;i++){
cin>>a;
A.push_back(a);//All the elements
}
cout<<fja(A,k);
}
I implemented non-recursive version, only loop-based, but it has O(k * n^4) so for biggest 10^5 values of N and k it will be too slow.
I provided recursive solution for reference, it can solve for N and k up to 10, my non-recursive solution can solve up to N and k of 100.
I'm sure some loops can be removed in my solution by algorithmic optimization. Still I could not figure out how to solve task for very large values of 10^5.
In current main() function N and k both are 10, for testing only, to leave only fast version you may change N and k from 10 to 100 and comment out f_ref() call. f_ref() is reference recursive function, f_fast() is my faster variant.
Try it online!
#include <cstdint>
#include <vector>
#include <iostream>
typedef uint32_t u32;
typedef int64_t i64;
typedef uint64_t u64;
enum { mod = 100000007 };
i64 f_ref(std::vector<i64> const & T, size_t begin, size_t end, size_t k) {
i64 sum = 0;
if (k == 0)
for (size_t i = begin; i < end; ++i)
sum = (sum + T[i]) % mod;
else
for (size_t i = begin; i < end; ++i)
for (size_t j = i; j < end; ++j)
sum = (sum + f_ref(T, i, j + 1, k - 1)) % mod;
return sum;
}
i64 f_fast(std::vector<i64> const & T, size_t k) {
size_t N = T.size();
std::vector<std::vector<i64>> mc, mn;
for (size_t n = 1; n <= N; ++n) {
mc.resize(mc.size() + 1);
for (size_t j = 0; j < n; ++j)
mc.back().push_back(((n + (n - 2 * j)) * (j + 1) / 2) % mod);
}
for (size_t ik = 0; ik + 1 < k; ++ik) {
mn.clear();
mn.resize(N);
for (size_t n = 1; n <= N; ++n) {
mn[n - 1].resize(n);
for (size_t i = 0; i < n; ++i)
for (size_t j = i; j < n; ++j)
for (size_t l = 0; l <= j - i; ++l)
mn[n - 1][i + l] = (mn[n - 1][i + l] + mc[j - i][l]) % mod;
}
mc = mn;
}
i64 sum = 0;
for (size_t i = 0; i < N; ++i)
sum = (sum + mc.back()[i] * (T[i] % mod)) % mod;
return sum;
}
int main() {
std::vector<i64> a;
for (size_t i = 0; i < 10; ++i)
a.push_back(i + 1);
size_t k = 10;
std::cout << f_ref(a, 0, a.size(), k) << " " << f_fast(a, k) << std::endl;
return 0;
}
Output for N = 10 and k = 10:
78689325 78689325
Output for N = 100 and k = 100:
37190121
I faced this problem in an interview challenge
K caterpillars are eating their way through N leaves, each caterpillar
falls from leaf to leaf in a unique sequence, all caterpillars start
at a twig at position 0 and falls onto the leaves at position between
1 and N. Each caterpillar j has an associated jump number Aj. A
caterpillar with jump number j eats leaves at positions that are
multiple of j. It will proceed in the order j, 2j, 3j…. till it
reaches the end of the leaves and it stops and build its cocoon. Given
a set A of K elements , we need to determine the number
of uneaten leaves.
Constraints:
1 <= N <= 109
1 <= K <= 15
1 <= A[i] <= 109
Input format:
N = No of uneaten leaves.
K = No. of caterpillars.
A = Array of integer.
jump numbers Output:
The integer nu. Of uneaten leaves
Sample Input:
10
3
2
4
5
Output:
4
Explanation:
[2, 4, 5] is the 3-member set of jump numbers. All leaves which are multiple of 2, 4, and 5 are eaten. Only 4 leaves which are numbered 1,3,7,9 are left.
the naive approach for solving this question is have a Boolean array of all N numbers, and iterate over every caterpillar and remember the eaten leaves by it.
int uneatenusingNaive(int N, vector<int> A)
{
int eaten = 0;
vector<bool>seen(N+1, false);
for (int i = 0; i < A.size(); i++)
{
long Ai = A[i];
long j = A[i];
while (j <= N && j>0)
{
if (!seen[j])
{
seen[j] = true;
eaten++;
}
j += Ai;
}
}
return N - eaten;
}
this approach passed 8 out of 10 test cases and give wrong answer for 2 cases.
another approach using Inclusion Exclusion principle, explanation for it can be found here and here
below is my code for the second approach
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a%b);
}
int lcm(int i, int j)
{
return i*j / gcd(i, j);
}
vector<vector<int>> mixStr(vector<vector<int>> & mix, vector<int>& A, unordered_map<int, int> & maxStart)
{
vector<vector<int>> res;
if (mix.size() == 0)
{
for (int i = 0; i < A.size(); i++)
{
vector<int> tmp;
tmp.push_back(A[i]);
res.push_back(tmp);
}
return res;
}
for (int i = 0; i<mix.size(); i++)
{
int currSlotSize = mix[i].size();
int currSlotMax = mix[i][currSlotSize - 1];
for (int j = maxStart[currSlotMax]; j < A.size(); j++)
{
vector<int> tmp(mix[i]);
tmp.push_back(A[j]);
res.push_back(tmp);
}
}
return res;
}
int uneatenLeavs(int N, int k, vector<int> A)
{
int i = 0;
vector<vector<int>> mix;
bool sign = true;
int res = N;
sort(A.begin(), A.end());
unordered_map<int,int> maxStart;
for (int i = 0; i < A.size(); i++)
{
maxStart[A[i]] = i + 1;
}
int eaten = 0;
while (mix.size() != 1)
{
mix = mixStr(mix, A, maxStart);
for (int j = 0; j < mix.size(); j++)
{
int _lcm = mix[j][0];
for (int s = 1; s < mix[j].size(); s++)
{
_lcm = lcm(mix[j][s], _lcm);
}
if (sign)
{
res -= N / _lcm;
}
else
{
res += N / _lcm;
}
}
sign = !sign;
i++;
}
return res;
}
this approach passed only one 1/10 test case. and for the rest of test cases time limit exceeded and wrong answer.
Question:
What am I missing in first or second approach to be 100% correct.
Using Inclusion-Exclusion theorem is correct approach, however, your implementation seems to be too slow. We can use bitmasking technique to obtain a O(K*2^K) time complexity.
Take a look at this:
long result = 0;
for(int i = 1; i < 1 << K; i++){
long lcm = 1;
for(int j = 0; j < K; j++)
if(((1<<j) & i) != 0) //if bit j is set, compute new LCM after including A[j]
lcm *= A[j]/gcd(lcm, A[j]);
if(number of bit set in i is odd)
result += N/lcm;
else
result -= N/lcm;
}
For your first approach, an O(N*K) time complexity algorithm, with N = 10^9 and K = 15, it will be too slow, and can cause memory limit exceed/time limit exceed.
Notice that lcm can be larger than N, so, additional check is needed.
i checked the answer and it's not off by much from my answer, but it is still an error. can someone check my coding to see what mistake caused me to get a value of 1319?
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int k = 0;
int o = 0;
vector<int> n(1,0);
n[0] = 1;
while (k < 1001)
{
for (int l = 0; l < n.size(); l++)
n[l] = n[l] * 2;
for (int l = 0; l < n.size(); l++)
{
if (n[l] >= 1000000)
{
int m;
if (l == n.size() - 1)
n.resize(n.size() + 1);
m = n[l] / 1000000;
n[l] = n[l] % 1000000;
n[l+1] = n[l+1] + m;
}
}
k++;
}
for (int l = 0; l < n.size(); l++)
o = o + int (n[l]/1000000) + int ((n[l] % 1000000) / 100000) + int ((n[l] % 100000) / 10000) + int ((n[l] % 10000) / 1000) + int ((n[l] % 1000) / 100) + int ((n[l] % 100) / 10) + n[l] % 10;
cout << o;
cin >> k;
return 0;
}
Make it
while (k < 1000)
in the outer loop condition.
In the while loop, you start with a representation of 2^k in the vector with the value k has at entering the loop. So you are actually computing 2^1001 and not 2^1000.
Problem of solving this in c++ is datatype limit, "int" is not sufficient to calculate 2^1000.
I have solved a prototype for this i.e. sum of the digits of number 2^4.The power 2^4 is 16 and sum of digits id 7.
Hope the code guides u.
#include<iostream.h>
#include<conio.h>
void main()
{
int count=1;
int power=1;
int sum=0;
while(count<=4)
{ count++;
power=power*2;
}
cout<<"The power is"<<power<<"\t";
while(power!=0)
{
int digit=power%10;
sum=sum+digit;
power=power/10;
}
cout<<"The sum of digits is"<<sum;
getch();
}