Open In App

String with frequency of characters in Lucas Sequence

Last Updated : 24 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string ‘str’ containing lowercase English alphabets, the task is to find whether the frequencies of the characters of the string are in Lucas sequence or not. You are free to arrange the frequency numbers in any way, in order to form the Lucas sequence. If possible then print YES otherwise NO. Lucas Sequence

Note: All the frequencies must be used to check if they are in Lucas Sequence. 

Examples:

Input: str = “gggeek” 
Output: YES frequency of ‘g’ = 3 frequency of ‘e’ = 2 frequency of ‘k’ = 1 These frequency can be arranged to form first 3 terms of Lucas sequence, {2, 1, 3}. 

Input: str = “geeksforgeeks” 
Output: NO

Approach:

  • Store the frequency of each character in a vector using map STL. Sort the vector afterwards.
  • Change the first and second element of first vector to ‘2’ and ‘1’ respectively, since Lucas sequence has ‘2’ and ‘1’ as first two numbers. However, change must only be made if ‘1’ and ‘2’ are present in the vector. If it is not present, then the frequencies can never be in Lucas sequence and output NO.
  • Then, make another vector. Let the size of first vector be n.
  • Insert first ‘n’ Lucas numbers in the 2nd vector.
  • Then, compare each element in both vectors. If both vectors are same, output ‘YES’, otherwise output ‘NO’.

Below is the implementation of the above approach: 

C++




// C++ implementation of
// the approach
#include <bits/stdc++.h>
using namespace std;
 
// function that checks
// if the frequencies
// are in Lucas sequence.
string lucas_sequence(string s, int n)
{
    // map is used to store
    // character frequencies
    map<char, int> m;
    for (int i = 0; i < n; i++) {
        if (m.find(s[i]) == m.end())
            m[s[i]] = 1;
        else
            m[s[i]]++;
    }
 
    vector<int> v1, v2;
 
    map<char, int>::iterator it;
 
    // frequencies are extracted from
    // map and stored in vector v1
    for (it = m.begin(); it != m.end(); it++)
        v1.push_back((*it).second);
 
    // vector v1 elements are sorted,
    // but first and second element are
    // changed to '2' and '1' respectively,
    // only if '1' and '2' are present in the vector.
    sort(v1.begin(), v1.end());
    if (v1[0] == 1 && v1[1] == 2) {
        v1[0] = 2;
        v1[1] = 1;
    }
    else
        return "NO";
 
    // a and b are first and
    // second terms of
    // Lucas sequence
    int a = 2, b = 1;
    int c;
    v2.push_back(a);
    v2.push_back(b);
 
    // v2 contains Lucas sequence
    for (int i = 0; i < v1.size() - 2; i++) {
        v2.push_back(a + b);
        c = a + b;
        a = b;
        b = c;
    }
    int flag = 1;
 
    // both vectors are compared
    for (int i = 0; i < v1.size(); i++) {
        if (v1[i] != v2[i]) {
            flag = 0;
            break;
        }
    }
 
    if (flag == 1)
        return "YES";
    else
        return "NO";
}
 
// Driver code
int main()
{
    string s = "oooeeeeqkk";
    int n = s.length();
    cout << lucas_sequence(s, n);
    return 0;
}


Java




// Java implementation of the approach
import java.util.Collections;
import java.util.HashMap;
import java.util.Vector;
 
class GFG
{
 
    // function that checks
    // if the frequencies
    // are in Lucas sequence.
    static String lucas_sequence(String s,
                                 int n)
    {
 
        // map is used to store
        // character frequencies
        HashMap<Character,
                Integer> m = new HashMap<>();
        for (int i = 0; i < n; i++)
            m.put(s.charAt(i),
            m.get(s.charAt(i)) == null ? 1 :
            m.get(s.charAt(i)) + 1);
 
        Vector<Integer> v1 = new Vector<>();
        Vector<Integer> v2 = new Vector<>();
 
        // frequencies are extracted from
        // map and stored in vector v1
        for (HashMap.Entry<Character,
                           Integer> entry : m.entrySet())
            v1.add(entry.getValue());
 
        // vector v1 elements are sorted,
        // but first and second element are
        // changed to '2' and '1' respectively,
        // only if '1' and '2' are present in the vector.
        Collections.sort(v1);
        if (v1.elementAt(0) == 1 &&
            v1.elementAt(1) == 2)
        {
            v1.set(0, 2);
            v1.set(1, 1);
        }
        else
            return "NO";
 
        // a and b are first and
        // second terms of
        // Lucas sequence
        int a = 2, b = 1;
        int c;
        v2.add(a);
        v2.add(b);
 
        // v2 contains Lucas sequence
        for (int i = 0; i < v1.size() - 2; i++)
        {
            v2.add(a + b);
            c = a + b;
            a = b;
            b = c;
        }
        int flag = 1;
 
        // both vectors are compared
        for (int i = 0; i < v1.size(); i++)
        {
            if (v1.elementAt(i) != v2.elementAt(i))
            {
                flag = 0;
                break;
            }
        }
 
        if (flag == 1)
            return "YES";
        else
            return "NO";
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String s = "oooeeeeqkk";
        int n = s.length();
        System.out.println(lucas_sequence(s, n));
    }
}
 
// This code is contributed by
// sanjeev2552


Python3




# Python3 implementation of the approach
from collections import defaultdict
 
# Function that checks if the
# frequencies are in Lucas sequence.
def lucas_sequence(s, n):
 
    # map is used to store
    # character frequencies
    m = defaultdict(lambda:0)
     
    for i in range(0, n):
        m[s[i]] += 1   
 
    v1, v2 = [], []
 
    # frequencies are extracted from
    # map and stored in vector v1
    for it in m:
        v1.append(m[it])
 
    # vector v1 elements are sorted, but
    # first and second element are changed
    # to '2' and '1' respectively, only if
    # '1' and '2' are present in the vector.
    v1.sort()
    if v1[0] == 1 and v1[1] == 2:
        v1[0], v1[1] = 2, 1
     
    else:
        return "NO"
 
    # a and b are first and second terms
    # of Lucas sequence
    a, b = 2, 1
    v2.append(a)
    v2.append(b)
 
    # v2 contains Lucas sequence
    for i in range(0, len(v1) - 2):
        v2.append(a + b)
        a, b = b, a + b
     
    flag = 1
 
    # both vectors are compared
    for i in range(0, len(v1)):
        if v1[i] != v2[i]:
            flag = 0
            break
 
    if flag == 1:
        return "YES"
    else:
        return "NO"
 
# Driver code
if __name__ == "__main__":
 
    s = "oooeeeeqkk"
    n = len(s)
    print(lucas_sequence(s, n))
 
# This code is contributed by Rituraj Jain


C#




// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // function that checks
    // if the frequencies
    // are in Lucas sequence.
    static String lucas_sequence(String s,
                                 int n)
    {
 
        // map is used to store
        // character frequencies
        Dictionary<char,
                   int> m = new Dictionary<char,
                                           int>();
        for (int i = 0; i < n; i++)
        {
            if(m.ContainsKey(s[i]))
            {
                m[s[i]] = m[s[i]] + 1;
            }
            else
            {
                m.Add(s[i], 1);
            }
        }
        List<int> v1 = new List<int>();
        List<int> v2 = new List<int>();
 
        // frequencies are extracted from
        // map and stored in vector v1
        foreach(KeyValuePair<char,
                             int> entry in m)
            v1.Add(entry.Value);
 
        // vector v1 elements are sorted,
        // but first and second element are
        // changed to '2' and '1' respectively,
        // only if '1' and '2' are present in the vector.
        v1.Sort();
        if (v1[0] == 1 &&
            v1[1] == 2)
        {
            v1[0] = 2;
            v1[1] = 1;
        }
        else
            return "NO";
 
        // a and b are first and
        // second terms of
        // Lucas sequence
        int a = 2, b = 1;
        int c;
        v2.Add(a);
        v2.Add(b);
 
        // v2 contains Lucas sequence
        for (int i = 0; i < v1.Count - 2; i++)
        {
            v2.Add(a + b);
            c = a + b;
            a = b;
            b = c;
        }
        int flag = 1;
 
        // both vectors are compared
        for (int i = 0; i < v1.Count; i++)
        {
            if (v1[i] != v2[i])
            {
                flag = 0;
                break;
            }
        }
 
        if (flag == 1)
            return "YES";
        else
            return "NO";
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        String s = "oooeeeeqkk";
        int n = s.Length;
        Console.WriteLine(lucas_sequence(s, n));
    }
}
 
// This code is contributed by Rajput-Ji


Javascript




function lucasSequence(s, n) {
  let m = new Map();
 
  for (let i = 0; i < n; i++) {
    if (!m.has(s[i])) {
      m.set(s[i], 1);
    } else {
      m.set(s[i], m.get(s[i]) + 1);
    }
  }
 
  let v1 = [], v2 = [];
 
  for (let [key, value] of m) {
    v1.push(value);
  }
 
  v1.sort();
 
  if (v1[0] === 1 && v1[1] === 2) {
    v1[0] = 2;
    v1[1] = 1;
  } else {
    return "NO";
  }
 
  let a = 2, b = 1, c;
  v2.push(a);
  v2.push(b);
 
  for (let i = 0; i < v1.length - 2; i++) {
    v2.push(a + b);
    c = a + b;
    a = b;
    b = c;
  }
 
  let flag = 1;
 
  for (let i = 0; i < v1.length; i++) {
    if (v1[i] !== v2[i]) {
      flag = 0;
      break;
    }
  }
 
  return flag === 1 ? "YES" : "NO";
}
 
let s = "oooeeeeqkk";
let n = s.length;
console.log(lucasSequence(s, n));


Output

YES


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads