Sunday, February 3, 2019

Hash Tables: Ransom Note - Hacker Rank Solution

Check out the resources on the page's right side to learn more about hashing. The video tutorial is by Gayle Laakmann McDowell, author of the best-selling interview book Cracking the Coding Interview.
Harold is a kidnapper who wrote a ransom note, but now he is worried it will be traced back to him through his handwriting.
He found a magazine and wants to know if he can cut out whole words from it and use them to create an untraceable replica of his ransom note. The words in his note are case-sensitive and he must use only whole words available in the magazine. He cannotuse substrings or concatenation to create the words he needs.
Given the words in the magazine and the words in the ransom note, print Yes if he can replicate his ransom note exactly using whole words from the magazine; otherwise, print No.
For example, the note is "Attack at dawn". The magazine contains only "attack at dawn". The magazine has all the right words, but there's a case mismatch. The answer is .
Function Description
Complete the checkMagazine function in the editor below. It must print  if the note can be formed using the magazine, or .
checkMagazine has the following parameters:
  • magazine: an array of strings, each a word in the magazine
  • note: an array of strings, each a word in the ransom note
Input Format
The first line contains two space-separated integers,  and , the numbers of words in the  and the ..
The second line contains  space-separated strings, each .
The third line contains  space-separated strings, each .
Constraints
  • .
  • Each word consists of English alphabetic letters (i.e.,  to  and  to ).
Output Format
Print Yes if he can use the magazine to create an untraceable replica of his ransom note. Otherwise, print No.
Sample Input 0
6 4
give me one grand today night
give one grand today
Sample Output 0
Yes
Sample Input 1
6 5
two times three is not four
two times two is four
Sample Output 1
No
Explanation 1
'two' only occurs once in the magazine.
Sample Input 2
7 4
ive got a lovely bunch of coconuts
ive got some coconuts
Sample Output 2
No
Explanation 2
Harold's magazine is missing the word .

Hash Tables: Ransom Note - Hacker Rank Solution

We have a multiset of words in a magazine, , and a multiset of words in a ransom note, . If  is contained in , then we print Yes because we can recreate the note; otherwise, we print No.

Approach

To solve this challenge, we use two maps:
  1. , which maps each word in  to its frequency.
  2. , which maps each word in  to its frequency.
Because we only care that all the words in  are contained in , we simply iterate over 's keyset and answer the following questions:
  1. Does the key (from 's keyset) exist in ?
  2. If the key exists in both maps, is the value associated with that key in  less than the value associated with the key in ?
If we answer no to the first question, we know that the magazine doesn't contain all the whole words we need to recreate the note. If we answer no to the second question, then we know that the word exists in the magazine but it simply does not occur enough times for us to recreate the entire note.
Problem Setter's code:

C++

#include <bits/stdc++.h>

using namespace std;

int main() {
    int m;  //number of words in magazine
    int n;  //number of words in notes
    cin >> m >> n;
    
    map<string, int> magazine; //map to store words in magazine with its frequency
    map<string, int> note;    //map to store words in notes with its frequency
    
    string word;
    
    for(int i = 0; i < m; i++) {
        cin >> word;
        magazine[word]++;
    }
    
    for(int i = 0; i < n; i++) {
        cin >> word;
        note[word]++;
    }
    
    map<string, int> :: iterator it;
    bool success = 1;
    
    //iterate over note map to check whether all words are present in map or not
    for(it = note.begin(); it != note.end(); it++) {
        if(magazine[it->first] < it->second) {
            success = 0;
            break;
        }
    }
    
    if(success) {
        cout << "Yes";
    }
    else {
        cout << "No";
    }

    return 0;
}
Problem Tester's code:

Java

import java.util.*;

public class Solution {
    Map<String, Integer> magazineMap;
    Map<String, Integer> noteMap;
    
    public Solution(String magazine, String note) {
        this.noteMap = new HashMap<String, Integer>();
        this.magazineMap = new HashMap<String, Integer>();
        
        // Must use an object instead of a primitive because it may be assigned a null reference.
        Integer occurrences;
        
        for(String s : magazine.split("[^a-zA-Z]+")) {
            occurrences = magazineMap.get(s);
            
            if(occurrences == null) {
                magazineMap.put(s, 1);
            }
            else {
                magazineMap.put(s, occurrences + 1);
            }
        }
        
        for(String s : note.split("[^a-zA-Z]+")) {
            occurrences = noteMap.get(s);
            
            if(occurrences == null) {
                noteMap.put(s, 1);
            }
            else {
                noteMap.put(s, occurrences + 1);
            }
        }
        
    }
    
    public void solve() {
        boolean canReplicate = true;
        for(String s : noteMap.keySet()) {
            if(!magazineMap.containsKey(s) || (magazineMap.get(s) < noteMap.get(s)) ) {
                canReplicate = false;
                break;
            }
        }
        
        System.out.println( (canReplicate) ? "Yes" : "No" );
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int m = scanner.nextInt();
        int n = scanner.nextInt();
        
        // Eat whitespace to beginning of next line
        scanner.nextLine();
        
        Solution s = new Solution(scanner.nextLine(), scanner.nextLine());
        scanner.close();
        
        s.solve();
    }
}

12 comments:

  1. #!/bin/python3

    import math
    import os
    import random
    import re
    import sys

    # Complete the checkMagazine function below.
    def checkMagazine(magazine, note):
    str1 = magazine
    str2 = note
    mylist = str2.split(" ")
    # print(mylist)
    # print(len(mylist))
    count = 0
    for i in range(len(mylist)):
    if str1.__contains__(mylist[i]):
    #str1 = str1.replace(mylist[i], ' ')
    count += 1
    if str1.index(mylist[i]) > 0:
    str1 = str1[:str1.index(mylist[i]) - 1] + str1[str1.index(mylist[i]) + len(mylist[i]):]
    else:
    str1 = str1[str1.index(mylist[i]) + len(mylist[i]):]
    if count == len(mylist):
    print("Yes")
    else:
    print("No")
    if __name__ == '__main__':
    mn = input().split()
    m = int(mn[0])
    n = int(mn[1])
    magazine = input()
    note = input()
    checkMagazine(magazine, note)

    ReplyDelete
  2. What is wrong with this solution?
    Missing 8/22 test cases.

    void checkMagazine(vector magazine, vector note) {
    int count = 0;
    for(int j = 0; j < note.size(); j++){
    for(int i = j; i < magazine.size(); i++){
    if(note[j].compare(magazine[i]) == 0){
    break;
    }
    if(note[j].compare(magazine[i]) != 0 && i == magazine.size()-1){
    count++;
    }
    }
    }
    if(count == 0){
    cout << "Yes" << '\n';
    }
    if(count > 0){
    cout << "No" << '\n';
    }
    }

    ReplyDelete
  3. how to solve when time limit exceeds?

    ReplyDelete
    Replies
    1. should try reduce the loops or nested loops in your code..

      Delete
  4. Other python solution:
    def checkMagazine(magazine, note):
    magazine.sort()
    note.sort()

    for word in note:
    try:
    r = magazine.index(word)
    except ValueError:
    print("No")
    return
    del magazine[r]

    print("Yes")

    ReplyDelete
  5. Python Implementation that worked for me:

    from collections import Counter

    # Complete the checkMagazine function below.
    def checkMagazine(magazine, note):
    if Counter(note) - Counter(magazine) == {}:
    print("Yes")
    else:
    print("No")

    ReplyDelete
    Replies
    1. if you don't mind...can you please explain if condition ..it worked but i didn't get it....

      Delete
  6. #!/bin/python3

    import math
    import os
    import random
    import re
    import sys

    #
    # Complete the 'checkMagazine' function below.
    #
    # The function accepts following parameters:
    # 1. STRING_ARRAY magazine
    # 2. STRING_ARRAY note
    #

    def checkMagazine(magazine, note):
    # Write your code here
    c = True
    try :
    for i in note :
    index = magazine.index(i)
    del magazine[index]
    except:
    print("No")
    c = False
    if c :
    print("Yes")

    if __name__ == '__main__':
    first_multiple_input = input().rstrip().split()

    m = int(first_multiple_input[0])

    n = int(first_multiple_input[1])

    magazine = input().rstrip().split()

    note = input().rstrip().split()

    checkMagazine(magazine, note)


    -----------------------------------------------------------
    simple code by deleting the magazine charactors

    ReplyDelete
  7. def checkMagazine(magazine, note):
    # Write your code here
    c = True
    try :
    for i in note :
    index = magazine.index(i)
    del magazine[index]
    except:
    print("No")
    c = False
    if c :
    print("Yes")

    ReplyDelete
  8. def checkMagazine(magazine, note):
    # Write your code here
    c = True
    try :
    ...for i in note :
    ......index = magazine.index(i)
    ......del magazine[index]
    except:
    ...print("No")
    ...c = False
    if c :
    ...print("Yes")

    ReplyDelete

Powered by Blogger.