Huffman Encoding | Practice | GeeksforGeeks

Given a string S of distinct character of size N and their corresponding frequency f[ ] i.e. character S[i] has f[i] frequency. Your task is to build the Huffman tree print all the huffman codes in preorder traversal of the tree.
Note: While merging if two nodes have the same value, then the node which occurs at first will be taken on the left of Binary Tree and the other one to the right, otherwise Node with less value will be taken on the left of the subtree and other one to the right.
Example 1:
S = "abcdef"
f[] = {5, 9, 12, 13, 16, 45}
Output: 
0 100 101 1100 1101 111
Explanation:

HuffmanCodes will be:
f : 0
c : 100
d : 101
a : 1100
b : 1101
e : 111
Hence printing them in the PreOrder of Binary 
Tree.
Your Task:
You don't need to read or print anything. Your task is to complete the function huffmanCodes() which takes the given string S, frequency array f[ ] and number of characters N as input parameters and returns a vector of strings containing all huffman codes in order of preorder traversal of the tree.
Expected Time complexity: O(N * LogN) 
Expected Space complexity: O(N) 
Constraints:
1 ≤ N ≤ 26
0
utsavj5022 weeks ago
#User function Template for python3
from heapq import heapify, heappush, heappop
class Node : 
    def __init__(self,freq,symbol,left=None,right=None) : 
        self.freq=freq
        self.symbol=symbol
        self.left=left
        self.right=right
    def __lt__(self, other):
        return self.freq < other.freq

class Solution:
    def traverse(self,root,ans,curr) : 
        if(root==None) : return;
        if(root.symbol!="$" and root.left==None and root.right==None) : 
            ans.append(curr)
            return;
        self.traverse(root.left,ans,curr+'0')
        self.traverse(root.right,ans,curr+'1')
        
    def huffmanCodes(self,S,f,N):
        heap=[]
        heapify(heap)
        for i in range(N) : 
            heappush(heap,Node(f[i],S[i]))
        while len(heap)>1 : 
            left=heappop(heap)
            right=heappop(heap)
            node=Node(left.freq+right.freq,"$",left,right)
            heappush(heap,node)
        ans=[]
        self.traverse(heappop(heap),ans,"")
        return ans
        # Code here

#{ 
#  Driver Code Starts
#Initial Template for Python 3


if __name__ == '__main__':
	t=int(input())
	for i in range(t):
		S= input()
		N= len(S);
		f= [int(x) for x in input().split()]
		ob = Solution()
		ans = ob.huffmanCodes(S,f,N)
		for i in ans:
		    print(i, end = " ")
		print()
# } Driver Code Ends
0
revolverocelot3 weeks ago
For C++. Athough using greater<int> gurantees the constraint mentioned in the ‘note’ of this question. However after running a test case I saw it actually violates it, which results in the testcase getting failed.
So instead of greater<>, while intialising prioirty_queue, define your own comparator block as under
struct comp       {           bool operator()( yourDataType a, yourDataType b)           {               return a→data > b→data;           }       };
0
sunboykenneth1 month ago
class HuffmanNode {
public:
    int weight;
    char charContent;
    
    HuffmanNode* leftChild;
    HuffmanNode* rightChild;
    
public:
    HuffmanNode (char charContent, int weight) {
        this->charContent = charContent;
        this->weight = weight;
        leftChild = rightChild = NULL;
    }
};

class CompareHuffmanNode {
public:
    bool operator()(HuffmanNode* const& p1, HuffmanNode* const& p2)
    {
        return p1->weight > p2->weight;
    }
};


class Solution
{
    private:
    void fetchAllEncodes(const HuffmanNode *root, string &path, vector<string> &resultCollection) {
        if (root->leftChild == NULL && root->rightChild == NULL) {
            resultCollection.push_back(path);
            return;
        }
        
        path += '0';
        fetchAllEncodes((root->leftChild), path, resultCollection);
        path.pop_back();
        path += '1';
        fetchAllEncodes((root->rightChild), path, resultCollection);
        path.pop_back();
    }
    
	public:
		vector<string> huffmanCodes(string S,vector<int> f,int N)
		{
		    if (N == 0) {
		        return {};
		    }
		    
		    if (N == 1) {
		        return {"0"};
		    }
		    
		    priority_queue<HuffmanNode*, vector<HuffmanNode*>, CompareHuffmanNode> q;
		    
		    for (int i = 0; i < N; i++) {
		        q.push(new HuffmanNode(S[i], f[i]));
		    }
		
		    while (q.size() > 1) {
		        HuffmanNode* node1 = q.top();
		        q.pop();
		        HuffmanNode* node2 = q.top();
		        q.pop();
		        
		        HuffmanNode* combinedNode = new HuffmanNode('\0', node1->weight + node2->weight);
		        combinedNode->leftChild = node1;
		        combinedNode->rightChild = node2;
	
		        q.push(combinedNode);
		    }
		    
		    HuffmanNode* root = q.top();
		    vector<string> resultCollection;
		    string path;
		    
		    fetchAllEncodes(root, path, resultCollection);
		    return resultCollection;
		}
};
0
harrypotter01 month ago
import heapq
from functools import total_ordering
@total_ordering
class Node(object):
   def __init__(self, freq, char=None, left=None, right=None):
       self.freq = freq
       self.char = char
       self.left = left
       self.right = right
   
   def __lt__(self, other):
       return self.freq < other.freq
   
   def __eq__(self, other):
       return self.freq == other.freq
   
   def __str__(self):
       return '(' + str(self.freq) + ', ' + self.char + ')'
   
   def __repr__(self):
       return str(self)
def getCodes(root):
   ans = []
   def recurse(cur, path=''):
       if not cur.left and not cur.right:
           ans.append(path)
       if cur.left:
           recurse(cur.left, path+'0')
       if cur.right:
           recurse(cur.right, path+'1')
   recurse(root)
   return ans
class Solution:
   def huffmanCodes(self, chars,freqs, n):
       heap = []
       for c, f in zip(chars, freqs):
           heapq.heappush(heap, Node(f, c))
       
       while len(heap) > 1:
           node1 = heapq.heappop(heap)
           node2 = heapq.heappop(heap)
           heapq.heappush(heap, Node(node1.freq + node2.freq, None, node1, node2))
       return (getCodes(heap[0]))
 
0
ashutosh442 months ago
Can anyone explains why StringBuilder doesnot work?
 
public void getString(ArrayList<String> a,Node root,StringBuilder s){       if(root.c != '$'){           a.add(String.valueOf(s));           return;       }       getString(a,root.left,s.append("0"));       getString(a,root.right,s.append("1"));   }
 
0
siddhant072 months ago
struct treeNode{
	        int val;
	        char symbol;
	        treeNode* left;
	        treeNode* right;
	        treeNode(int v, char c, treeNode* l = NULL, treeNode *r = NULL){
	            val = v;
	            symbol = c;
	            left = l;
	            right = r;
	        }
	    };
	
	
	    struct comp{
	        bool operator()(treeNode * node1 , treeNode* node2){
	            return node1->val > node2->val;
	        }
	    };
	    
	    void preOrderTransversal(treeNode* root, vector<string> &ans, string curr = ""){
	        if(root == NULL){
	            return;
	        }
	        if(root->symbol != '$' && root->left == NULL && root->right == NULL){
	            ans.push_back(curr);
	            return;
	        }
	        preOrderTransversal(root->left, ans, curr + '0');
	        preOrderTransversal(root->right, ans, curr + '1');
	        return;
	    }
	    
	
		vector<string> huffmanCodes(string s,vector<int> f,int N)
		{
		    priority_queue<treeNode*, vector<treeNode*>, comp> pq;
		    for(int i = 0; i < N; i++){
		        pq.push(new treeNode(f[i], s[i]));
		    }
		    while(pq.size() > 1){
		        treeNode *l = pq.top();
		        pq.pop();
		        treeNode *r = pq.top();
		        pq.pop();
		        treeNode* node = new treeNode(l->val + r->val, '$', l, r);
		        pq.push(node);
		    }
		    vector<string> ans;
		    preOrderTransversal(pq.top(), ans, "");
		    return ans;
		}
+2
himanshukug19cs2 months ago
java solution
ArrayList<String> ans = new ArrayList<String>();   class Node implements Comparable<Node>{       int data;       Node left;       Node right;       Node(int data){           this.data=data;           this.left=left;           this.right=right;       }       public int compareTo(Node o){           if(this.data == o.data){               return 1;           }           return this.data-o.data;       }   }    void sol(Node root,String s){       if(root==null)           return;       if(root.left==null&&root.right==null){           ans.add(s);           return;       }           if(root.left!=null)            sol(root.left,s+"0");       if(root.right!=null)            sol(root.right,s+"1");          }public ArrayList<String> huffmanCodes(String S, int f[], int N)   {       // Code hereNode root=null;PriorityQueue<Node> pq = new PriorityQueue<>();for(int i=0;i<N;i++){   Node n = new Node(f[i]);   pq.add(n);}while(pq.size()>1){   Node l=pq.poll();   Node r=pq.poll();   root= new Node(l.data+r.data);   root.left=l;   root.right=r;   pq.add(root);   }root=pq.remove(); sol(root,""); return ans;   }   
+2
kumaarsahab4322 months ago
private: 
	//For making Huffman Tree
    struct Node{
        int data ;
        Node *left, *right ;
        Node(int x)
        {
            data=x ;
            left=NULL ;
            right=NULL ;
        }
    } ;
    
    //For making a Min Heap
    struct comp{
       bool operator()(Node *a, Node *b){
           return a->data > b->data;
       }
   };
	public:
			
		//For Encoding the Alphabets
	    void preorder(Node* root, vector<string> &ans, string c)
	    {
	        if(root==NULL) return ;
	        if(root->left==NULL and root->right==NULL)
	        {
	            ans.push_back(c) ;
	            return ; 
	        }
	        preorder(root->left, ans, c+"0") ;
	        preorder(root->right, ans, c+"1") ;
	    }
		vector<string> huffmanCodes(string S,vector<int> f,int N)
		{
		    vector<string> ans ;
		    priority_queue<Node*, vector<Node*>, comp> pq ;
		    
		    //For creating leaf nodes
		    for(int i=0 ; i<f.size() ; i++)
		    {
		        Node* temp=new Node(f[i]) ;
		        pq.push(temp) ;
		    }
		    
		    //Creating the Complete Huffman tree
		    while(pq.size()>1)
		    {
		        Node* x=pq.top() ;
		        pq.pop() ;
		        Node* y=pq.top() ;
		        pq.pop() ;
		        Node* temp=new Node(x->data+y->data) ;
		        temp->left=x ;
		        temp->right=y ;
		        pq.push(temp) ;
		    }
		    
		    preorder(pq.top(), ans, "") ;
		    return ans ;
		}
0
balamurali16012 months ago
class Solution {
    private static ArrayList<String> results = new ArrayList<>();

    public ArrayList<String> huffmanCodes(String S, int f[], int N)
    {
        results = new ArrayList<>();
        PriorityQueue<HuffManNode> priorityQueue = new PriorityQueue<>
                (N, Comparator.comparingInt(o -> o.characterCount));

        for (int i = 0; i < f.length; i++) {
            HuffManNode node = new HuffManNode();
            node.characterCount = f[i];
            node.character = S.charAt(i);
            priorityQueue.add(node);
        }

        HuffManNode root = null;

        while (priorityQueue.size() > 1) {
            HuffManNode firstNode = priorityQueue.poll();
            HuffManNode secondNode = priorityQueue.poll();

            HuffManNode newNode = new HuffManNode();
            newNode.characterCount = firstNode.characterCount + secondNode.characterCount;
            newNode.character = '-';
            newNode.left = firstNode;
            newNode.right = secondNode;

            root = newNode;
            priorityQueue.add(newNode);
        }

        printQueue(root, "");
        return results;
    }
    private static void printQueue(HuffManNode root, String s) {

        if (root.left == null && root.right == null && Character.isLetter(root.character)) {
            results.add(s);
            return;
        }
        printQueue(root.left, s + "0");
        printQueue(root.right, s + "1");

    }

    static class HuffManNode {
        char character;
        int characterCount;
        HuffManNode left;
        HuffManNode right;
    }
}
WHy this code not working?Input:  
qwertyuiopasdfghjklzxcvbn 8 9 14 19 20 21 21 25 33 45 50 50 66 68 70 73 74 75 76 82 85 90 94 97 100
And Your Code's output is: 
0000 0001 00100 001010 001011 0011 0100 0101 0110 0111 1000 100100 100101 10011 1010 1011 1100 1101 11100 11101 111100 1111010 11110110 11110111 11111
Its Correct output is: 
0000 0001 00100 001010 001011 0011 0100 0101 0110 0111 1000 100100 100101 10011 1010 1011 1100 11010 11011 1110 111100 1111010 11110110 11110111 11111
Output Difference 
0000 0001 00100 001010 001011 0011 0100 0101 0110 0111 1000 100100 100101 10011 1010 1011 1100 1101  11100  11101 111100 1111010 11110110 11110111 11111
+1
aloksinghbais022 months ago
C++ solution having time complexity as O(N*log(N)) and space complexity as O(N) is as follows :-
 
Note :- I have tried to solve using set but I got wrong answer so then I tried using priority queue and it got submitted.
If anyone else faces the same problem and get the solution then please respond.
 
Execution Time :- 0.0 / 1.6 sec
 
private:   class Node{       public:           int data;           Node *left;           Node *right;           Node(int data){               this->data = data;               left = right = nullptr;           }   };      struct comp{       bool operator()(Node *node1,Node *node2){           return node1->data > node2->data;       }   };   public:    void preorder(Node *node,string c,vector<string> &ans){        if(!node) return;        if(!node->left && !node->right){            ans.push_back(c);            return;        }                preorder(node->left,c + '0',ans);        preorder(node->right,c + '1',ans);    }     vector<string> huffmanCodes(string S,vector<int> f,int N){     priority_queue<Node*,vector<Node*>,comp> pq;     for(int i = 0; i < N; i++){         Node *node = new Node(f[i]);         pq.push(node);     }          while(pq.size() > 1){         Node *left = pq.top();         pq.pop();         Node *right = pq.top();         pq.pop();                  Node *root = new Node(left->data + right->data);         root->left = left;         root->right = right;                  pq.push(root);     }          Node *root = pq.top();     pq.pop();          vector<string> ans;     preorder(root,"",ans);          return (ans); }private:   class Node{       public:           int data;           Node *left;           Node *right;           Node(int data){               this->data = data;               left = right = nullptr;           }   };      struct comp{       bool operator()(Node *node1,Node *node2){           return node1->data > node2->data;       }   };   public:    void preorder(Node *node,string c,vector<string> &ans){        if(!node) return;        if(!node->left && !node->right){            ans.push_back(c);            return;        }                preorder(node->left,c + '0',ans);        preorder(node->right,c + '1',ans);    }     vector<string> huffmanCodes(string S,vector<int> f,int N){     priority_queue<Node*,vector<Node*>,comp> pq;     for(int i = 0; i < N; i++){         Node *node = new Node(f[i]);         pq.push(node);     }          while(pq.size() > 1){         Node *left = pq.top();         pq.pop();         Node *right = pq.top();         pq.pop();                  Node *root = new Node(left->data + right->data);         root->left = left;         root->right = right;                  pq.push(root);     }          Node *root = pq.top();     pq.pop();          vector<string> ans;     preorder(root,"",ans);          return (ans); }
We strongly recommend solving this problem on your own before viewing its editorial. Do you still
                    want to view the editorial?
 Login to access your submissions. 

Problem


Contest

Reset the IDE using the second button on the top right corner.
Avoid using static/global variables in your code as your code is tested against multiple test cases and these tend to retain their previous values.
Passing the Sample/Custom Test cases does not guarantee the correctness of code. On submission, your code is tested against multiple test cases consisting of all possible corner cases and stress constraints.
You can access the hints to get an idea about what is expected of you as well as the final solution code.
You can view the solutions submitted by other users from the submission tab.