Golomb sequence


Golomb Sequence − The Golomb Sequence is a non-decreasing sequence of integers where the value of the nth term is the number of times the integer n appeared in the sequence.

Some terms of Golomb sequence are,

1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, …

Here as we can see, the 5th term is 3 and 5 also appears 3 times in the sequence.

The 6th term is 4 and 6 also appears 4 times in the sequence.

Properties of Golomb Sequence − The first term of the sequence is 1 and the nth term is 1 + the number of terms in the sequence that are less than or equal to the n - nth term.

Problem Statement

Given an integer n. Find the first n terms in the Golomb sequence.

Sample Example 1

Input: n = 4
Output: [1, 2, 2, 3]

Sample Example 2

Input: n = 7
Output: [1, 2, 2, 3, 3, 4, 4]

Approach 1: Using Recursion

Using the properties of the Golomb Sequence, the first term of the sequence is 1. For finding the nth term, we use the property that the nth term is 1 + the number of terms in the sequence that are less than or equal to the n - nth term.

Applying this approach in a recursive function, we ensure the property is fulfilled if the nth term is the smallest positive integer that does not appear earlier in the sequence more than n - golomb(golomb(n - 1)) times where golomb() is the recursive function for finding the nth term of golomb sequence.

Pseudocode

procedure golomb (n)
   if n == 1
      ans = 1
   end if
   ans = 1 + golomb(n - golomb(golomb(n - 1)))
end procedure
procedure golombSeq (n)
   seq[n] = {0}
   for i = 1 to n
      seq[i - 1] = golomb(i)
   ans = seq
end procedure

Example: C++ Implementation

In the following program, we use recursion to find the golomb sequence.

#include <bits/stdc++.h>
using namespace std;

// Function to find golomb number
int golomb(int n){

   // First element is 1
   if (n == 1) {
      return 1;
   }
   
   // Satisfying property of golomb sequence for the nth number
   return 1 + golomb(n - golomb(golomb(n - 1)));
}

// Function to generate golomb sequence
vector<int> golombSeq(int n){
   vector<int> seq(n, 0);
   for (int i = 1; i <= n; i++){
      seq[i - 1] = golomb(i);    
      }
   return seq;
}
int main(){
   int n = 15;
   vector<int> seq = golombSeq(n);
   cout << "Golomb sequence up to " <<n << " terms: ";
   for (int i = 0; i < n; i++)    {
      cout << seq[i] << " ";
   }
   return 0;
} 

Output

Golomb sequence up to 15 terms: 1 2 2 3 3 4 4 4 5 5 5 6 6 6 6

Time Complexity − O(n^2) as each term is calculated by recursively calculating the previous terms.

Space Complexity − O(n)

Approach 2: Recursion with Memoization

For memoizing the recursive code, we create a map to store the previously computed values that were recursively computed in the above code. Then for calculating each number, it is first checked if the previous number is calculated or not, if it is then the previously calculated result is taken otherwise it is calculated.

Pseudocode

golomb (n, t)
   if n == 1
      ans = 1
   end if
   if n is present in t
      ans = t[n]
   end if
   ans = 1 + golomb(n - golomb(golomb(n - 1, t), t), t)
   t[n] = ans
end procedure
procedure golombSeq (n)
   seq[n] = {0}
   Initialize map: t
   for i = 1 to n
       seq[i - 1] = golomb(i, t)
   ans = seq
end procedure

Example: C++ Implementation

In the following program, previous calculations are stored in a map which is accessed at the time a term is being calculated.

#include <bits/stdc++.h>
using namespace std;

// Function to find golomb number
int golomb(int n, map<int, int> &t){

   // First term is 1
   if (n == 1){
      return 1;
   }
   
   // Checking if the term is previously computed
   if (t.find(n) != t.end()){
      return t[n];
   }
   int result = 1 + golomb(n - golomb(golomb(n - 1, t), t), t);
   
   // Saving the term to map
   t[n] = result;
   return result;
}

// Function to generate golomb sequence
vector<int> golombSeq(int n){
   vector<int> seq(n, 0);
   map<int, int> t;
   for (int i = 1; i <= n; i++){
      seq[i - 1] = golomb(i, t);
   }
   return seq;
}
int main(){
   int n = 15;
   vector<int> seq = golombSeq(n);
   cout << "Golomb sequence up to " <<n << " terms: ";
   for (int i = 0; i < n; i++){
      cout << seq[i] << " ";
   }
   return 0;
}

Output

Golomb sequence up to 15 terms: 1 2 2 3 3 4 4 4 5 5 5 6 6 6 6

Time Complexity − O(nlogn)

Space Complexity − O(n)

Approach 3: Dynamic Programming

Using dynamic programming, we create a dp table of the size n+1 * 1. Then using the property used above where the nth number is 1 + golomb(n - golomb(golomb(n - 1))), calculate all the numbers in the sequence and store them in the vector.

Pseudocode

procedure golombSeq (n)
   seq[n] = {0}
   seq[0] = 1
      Initialize the dp table of size n+1, 1
   for i = 2 to n
      dp[i] = dp[i - dp[dp[i - 1]]] + 1
   for i = 1 to n
      seq[i-1] = dp[i]
   ans = seq
end procedure

Example: C++ Implementation

In the following program, we use a dynamic programming approach to solve the problem.

#include <bits/stdc++.h>
using namespace std;
// Function to generate golomb sequence
vector<int> golombSeq(int n){
   vector<int> seq(n, 0);
   
   // First term is 1
   seq[0] = 1;
   vector<int> dp(n + 1, 1);
   for (int i = 2; i <= n; i++){
   
      // Satisfying the property that nth term is 1 + golomb(n - golomb(golomb(n - 1)))
      dp[i] = dp[i - dp[dp[i - 1]]] + 1;
   }
   for (int i = 1; i <= n; i++){
      seq[i - 1] = dp[i];
   }
   return seq;
}
int main(){
   int n = 15;
   vector<int> seq = golombSeq(n);
   cout << "Golomb sequence up to " <<n << " terms: ";
   for (int i = 0; i < n; i++){
      cout << seq[i] << " ";
   }
   return 0;
}

Output

Golomb sequence up to 15 terms: 1 2 2 3 3 4 4 4 5 5 5 6 6 6 6 

Conclusion

In conclusion, for finding the golomb sequence we use the property of the nth number of the golomb sequence to find all the numbers in the sequence with various approaches having time complexities from O(n^2) to O(n).

Updated on: 25-Jul-2023

306 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements