Given an integer *n* and an array of characters *S*, the task is to generate Lyndon words of length *n* having characters from *S*.

A Lyndon word is a string which is strictly less than all of its rotations in lexicographic order. For example, the string “012” is a Lyndon word as it is less than its rotations “120” and “201”, but “102” is not a Lyndon word as it is greater than its rotation “021”.

Note:“000” is not considered to be a Lyndon word as it is equal to the string obtained by rotating it.

**Examples:**

Input:n = 2, S = {0, 1, 2}

Output:01

02

12

Other possible strings of length 2 are “00”, “11”, “20”, “21”, and “22”. All of these are either

greater than or equal to one of their rotations.

Input:n = 1, S = {0, 1, 2}

Output:0

1

2

**Approach:** There exists an efficient approach to generate Lyndon words which was given by Jean-Pierre Duval, which can be used to generate all the Lyndon words upto length n in time proportional to the number of such words. (Please refer to the paper “Average cost of Duval’s algorithm for generating Lyndon words” by Berstel et al. for the proof)

The algorithm generates the Lyndon words in a lexicographic order. If *w* is a Lyndon word, the next word is obtained by the following steps:

- Repeat
*w*to form a string*v*of length*n*, such that*v[i] = w[i mod |w|]*. - While the last character of
*v*is the last one in the sorted ordering of*S*, remove it. - Replace the last character of
*v*by its successor in the sorted ordering of S.

For example, if n = 5, S = {a, b, c, d}, and w = “add” then we get v = “addad”.

Since ‘d’ is the last character in the sorted ordering of S, we remove it to get “adda”

and then replace the last ‘a’ by its successor ‘b’ to get the Lyndon word “addb”.

Below is the implementation of the above approach:

## C++

`// C++ implementation of ` `// the above approach ` `#include<bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `int` `main() ` `{ ` ` ` `int` `n = 2; ` ` ` `char` `S[] = {` `'0'` `, ` `'1'` `, ` `'2'` `}; ` ` ` `int` `k = 3; ` ` ` `sort(S, S + 3); ` ` ` ` ` `// To store the indices ` ` ` `// of the characters ` ` ` `vector<` `int` `> w; ` ` ` `w.push_back(-1); ` ` ` ` ` `// Loop till w is not empty ` ` ` `while` `(w.size() > 0) ` ` ` `{ ` ` ` ` ` `// Incrementing the last character ` ` ` `w[w.size()-1]++; ` ` ` `int` `m = w.size(); ` ` ` `if` `(m == n) ` ` ` `{ ` ` ` `string str; ` ` ` `for` `(` `int` `i = 0; i < w.size(); i++) ` ` ` `{ ` ` ` `str += S[w[i]]; ` ` ` `} ` ` ` `cout << str << endl; ` ` ` `} ` ` ` ` ` `// Repeating w to get a ` ` ` `// n-length string ` ` ` `while` `(w.size() < n) ` ` ` `{ ` ` ` `w.push_back(w[w.size() - m]); ` ` ` `} ` ` ` ` ` `// Removing the last character ` ` ` `// as long it is equal to ` ` ` `// the largest character in S ` ` ` `while` `(w.size() > 0 && w[w.size() - 1] == k - 1) ` ` ` `{ ` ` ` `w.pop_back(); ` ` ` `} ` ` ` `} ` ` ` `return` `0; ` `} ` ` ` `// This code is contributed by AdeshSingh1 ` |

*chevron_right*

*filter_none*

## Python3

`# Python implementation of ` `# the above approach ` ` ` `n ` `=` `2` `S ` `=` `[` `'0'` `, ` `'1'` `, ` `'2'` `] ` `k ` `=` `len` `(S) ` `S.sort() ` ` ` `# To store the indices ` `# of the characters ` `w ` `=` `[` `-` `1` `] ` ` ` `# Loop till w is not empty ` `while` `w: ` ` ` ` ` `# Incrementing the last character ` ` ` `w[` `-` `1` `] ` `+` `=` `1` ` ` `m ` `=` `len` `(w) ` ` ` `if` `m ` `=` `=` `n: ` ` ` `print` `(''.join(S[i] ` `for` `i ` `in` `w)) ` ` ` ` ` `# Repeating w to get a ` ` ` `# n-length string ` ` ` `while` `len` `(w) < n: ` ` ` `w.append(w[` `-` `m]) ` ` ` ` ` `# Removing the last character ` ` ` `# as long it is equal to ` ` ` `# the largest character in S ` ` ` `while` `w ` `and` `w[` `-` `1` `] ` `=` `=` `k ` `-` `1` `: ` ` ` `w.pop() ` |

*chevron_right*

*filter_none*

**Output:**

01 02 12

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Count words that appear exactly two times in an array of words
- Check if the given string of words can be formed from words present in the dictionary
- Generating distinct subsequences of a given string in lexicographic order
- Generating hash id's using uuid3() and uuid5() in Python
- Generating subarrays using recursion
- Generating all possible Subsequences using Recursion
- Generating numbers that are divisor of their right-rotations
- Find words which are greater than given length k
- Find words which are greater than given length k using stringstream
- K length words that can be formed from given characters without repetition
- Java program to print Even length words in a String
- Minimum length of the sub-string whose characters can be used to form a palindrome of length K
- Maximum length L such that the sum of all subarrays of length L is less than K
- Construct a string of length L such that each substring of length X has exactly Y distinct letters
- Length of longest Palindromic Subsequence of even length with no two adjacent characters same
- Reverse words in a given string
- Given a sequence of words, print all anagrams together | Set 1
- Given a sequence of words, print all anagrams together | Set 2
- Count words in a given string
- Print all possible words from phone digits

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.