Skip to content

[Hacker Rank] Interview Preparation Kit: String Manipulation: Sherloc… #520

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# [String Manipulation: Sherlock and the Valid String](https://www.hackerrank.com/challenges/sherlock-and-valid-string)

- Difficulty: `#medium`
- Category: `#ProblemSolvinIntermediate` `#strings`

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 ´1´ character at index in the string,
and the remaining characters will occur the same number of times.
Given a string `s`, determine if it is valid.
If so, return `YES`, otherwise return `NO`.

## Example

`s = abc`

This is a valid string because frequencies are `{a: 1, b: 1, c: 1}`.

`s = abcc`

This is a valid string because we can remove one `c` and have of
each character in the remaining string.

`s = abccc`

This string is not valid as we can only remove `1` occurrence of `c`.
That leaves character frequencies of `{a: 1, b: 1, c: 2}`.

## Function Description

Complete the isValid function in the editor below.

isValid has the following parameter(s):

- `string s`: a string

## Returns

- `string`: either `YES` or `NO`

## Input Format

A single string `s`.

## Constraints

- $ 1 \leq |s| \leq 10^5 $
- Each character `s[i]` $ \in $ `ascii[a-z]`

## Sample Input 0

```text
aabbcd
```

## Sample Output 0

```text
NO
```

## Explanation 0

Given `s = "abbcd"`, 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 `s` is invalid.

## Sample Input 1

```text
aabbccddeefghi
```

## Sample Output 1

```text
NO
```

## Explanation 1

Frequency counts for the letters are as follows:

```text
{'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 `4` characters with a frequency of `1`: `{fghi}`.
- Remove `5` characters of frequency `2`: `{abcde}`.
Neither of these is an option.

## Sample Input 2

```text
abcdefghhgfedecba
```

## Sample Output 2

```text
YES
```

## Explanation 2

All characters occur twice except for `e` which occurs `3` times.
We can delete one instance of `e` to have a valid string.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* @link Problem definition [[docs/hackerrank/interview_preparation_kit/string_manipulation/sherlock-and-valid-string.md]]
*/

const __YES__ = 'YES';
const __NO__ = 'NO';

export function isValidCompute(s) {
if (s.length <= 1) {
return true;
}

const stringMap = {};

for (const letter of s.split('')) {
stringMap[letter] = stringMap?.[letter] ? stringMap[letter] + 1 : 1;
}

const frequencies = {};

for (const event of Object.values(stringMap)) {
frequencies[event] = frequencies?.[event] ? frequencies[event] + 1 : 1;
}

const frequenciesSize = Object.entries(frequencies).length;

if (frequenciesSize === 1) {
return true;
}

if (frequenciesSize === 2) {
const frequenciesList = Object.entries(frequencies).sort(
([, a], [, b]) => a - b
);
const __RADIX__ = 10;
const __TOLERANCE__ = 1;
const minorFreq = parseInt(frequenciesList[0][0], __RADIX__);
const majorFreq = parseInt(frequenciesList[1][0], __RADIX__);

if (
frequencies[minorFreq] === __TOLERANCE__ &&
(minorFreq === __TOLERANCE__ || minorFreq - majorFreq === __TOLERANCE__)
) {
return true;
}
}

return false;
}

export function isValid(s) {
return isValidCompute(s) ? __YES__ : __NO__;
}

export default { isValid };
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { describe, expect, it } from '@jest/globals';

import { isValid } from './sherlock_and_valid_string.js';
import TEST_CASES from './sherlock_and_valid_string.testcases.json';

describe('isValid', () => {
it('isValid test cases', () => {
expect.assertions(9);

const __YES__ = 'YES';

TEST_CASES.forEach((test) => {
const result = isValid(test.input) === __YES__;

expect(result).toStrictEqual(test.expected);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[
{
"title": "counterexample",
"input": "aabbccc",
"expected": true
},
{
"title": "counterexample",
"input": "a",
"expected": true
},
{
"title": "counterexample",
"input": "aaa",
"expected": true
},
{
"title": "counterexample",
"input": "abbccc",
"expected": false
},
{
"title": "counterexample",
"input": "bbccc",
"expected": false
},
{
"title": "Sample Test case 0",
"input": "aabbcd",
"expected": false
},
{
"title": "Sample Test case 1",
"input": "aabbccddeefghi",
"expected": false
},
{
"title": "Sample Test case 2",
"input": "abcdefghhgfedecba",
"expected": true
},
{
"title": "Sample Test case 4",
"input": "aabbc",
"expected": true
}
]