- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
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).