Sherlock considers a string to be valid if all characters of the string appear the same number of times. It is also valid if he can remove just character at index in the string, and the remaining characters will occur the same number of times.
Given a string , determine if it is valid. If so, return YES
, otherwise return NO
.
For example, if , it is a valid string because frequencies are . So is because we can remove one and have of each character in the remaining string. If however, the string is not valid as we can only remove occurrence of . That would leave character frequencies of .
Function Description
Complete the isValid function in the editor below. It should return either the string
YES
or the string NO
.
isValid has the following parameter(s):
- s: a string
Input Format
A single string .
Constraints
- Each character
Output Format
Print
YES
if string is valid, otherwise, print NO
.
Sample Input 0
aabbcd
Sample Output 0
NO
Explanation 0
Given , we would need to remove two characters, both
c
and d
aabb
or a
and b
abcd
, to make it valid. We are limited to removing only one character, so is invalid.
Sample Input 1
aabbccddeefghi
Sample Output 1
NO
Explanation 1
Frequency counts for the letters are as follows:
{'a': 2, 'b': 2, 'c': 2, 'd': 2, 'e': 2, 'f': 1, 'g': 1, 'h': 1, 'i': 1}
There are two ways to make the valid string:
- Remove characters with a frequency of : .
- Remove characters of frequency : .
Neither of these is an option.
Sample Input 2
abcdefghhgfedecba
Sample Output 2
YES
Explanation 2
All characters occur twice except for which occurs times. We can delete one instance of to have a valid string.
Sherlock and the Valid String - Hacker Rank Solution
An overview of the solution is to get a count of all distinct characters in the string and then test for valid conditions. Three cases exist that are valid strings:
- If all have the same frequency
- If only character has a frequency that is greater than all others
- If all have the same frequency except element which has a frequency of
Problem Setter's code:
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
set<int> myset;
string s;
cin >> s;
string ans = "NO";
// cnt[i] stores frequency of character i+'a'
int cnt[26] = {}, n = s.length();
for (int i = 0; i < n; i++) {
// increasing frequency
cnt[s[i] - 'a']++;
}
// for i>=0, it means we are removing character i+'a', if possible
// case i=-1 is for checking if string is already valid
for (int i = -1; i < 26; i++) {
// if character i+'a' is not present in string continue
if (i >= 0 and cnt[i] == 0)
continue;
// reduce frequency
if (i >= 0)
cnt[i]--;
// if we insert all positive frequencies into a set, it should contain
// only 1 element if string is now valid
set<int> myset;
// insert remaining positive frequencies into set
for (int j = 0; j < 26; j++) {
if (cnt[j])
myset.insert(cnt[j]);
}
// if set size is 1, string is now valid
if (myset.size() == 1)
ans = "YES";
// increase the frequency back again
if (i >= 0)
cnt[i]++;
}
cout << ans << endl;
return 0;
}
Problem Tester's code:
from collections import Counter
def isValid(s):
cnt = Counter(s)
if len(set(cnt.values())) == 1:
return "YES"
elif len(set(cnt.values())) > 2:
return "NO"
else:
m1 = max(cnt.values())
m2 = min(cnt.values())
if cnt.values().count(m2) == 1:
return "YES"
if cnt.values().count(m1) > 1 or m1 - m2 > 1:
return "NO"
return "YES"
s = raw_input().strip()
result = isValid(s)
print(result)
Another Solution (Editorial)
from collections import Counter
def check(cnt):
ls = cnt.values()
try:
ls.remove(0)
except:
pass
if len(set(ls)) == 1:
return True
else:
return False
def isValid(s):
cnt = Counter(s)
if check(cnt):
return "YES"
for i in cnt.keys():
cnt[i] -= 1
if check(cnt):
return "YES"
else:
cnt[i] += 1
return "NO"
s = raw_input().strip()
result = isValid(s)
print(result)
in c++ solution we could use a break statement inside if case of making ans = 'yes'. it will reduce execution time
ReplyDeletethere is an error .. raw_input() is not defined
ReplyDelete