Skip to content
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
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Algorithms (22/ 167)
## Algorithms (23/ 167)

| Name | Tags | Solution |
| --------------------------------------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
Expand All @@ -15,7 +15,7 @@
| Frequency Queries | `Hash Tables` | [TypeScript](./src/algorithms/hashtables/frequency-queries) |
| Making Anagrams | `Strings` | [TypeScript](./src/algorithms/strings/make-anagram) |
| Alternating Characters | `Strings` | [TypeScript](./src/algorithms/strings/alternating-characters) |
| Sherlock and the Valid String | `Strings` | |
| Sherlock and the Valid String | `Strings` | [TypeScript](./src/algorithms/strings/sherlock-and-the-valid-string) |
| Special String Again | `Strings` | |
| Common Child | `Strings` | |
| Contains-Duplicate | `Arrays`, `Hash Tables` | [TypeScript](./src/algorithms/arrays_hashtables/contains-duplicate) |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
*
* 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.
*
*
* Example:
* s = abc // => YES
*
* this is a valid string because frequencies are { a: 1, b: 1, c : 1}
*
*
* s = abccc // => NO
*
* 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}.
*
*/

export function isValid(s: string): string {
const charFrequency: Map<string, number> = new Map()

for (const char of s) {
charFrequency.set(char, (charFrequency.get(char) || 0) + 1)
}

const frequencyCount: Map<number, number> = new Map()

for (const freq of charFrequency.values()) {
frequencyCount.set(freq, (frequencyCount.get(freq) || 0) + 1)
}

const frequencies = Array.from(frequencyCount.keys())

if (frequencies.length === 1) return 'YES'

if (frequencies.length === 2) {
const [f1, f2] = frequencies
const high = Math.max(f1, f2)
const low = Math.min(f1, f2)

const highCount = frequencyCount.get(high)
const lowCount = frequencyCount.get(low)

const oneCharHasFreqOne = low === 1 && lowCount === 1
const oneCharHasExtra = high - low === 1 && highCount === 1

if (oneCharHasFreqOne || oneCharHasExtra) {
return 'YES'
}
}

return 'NO'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { isValid } from './sherlock-and-the-valid-string.'

describe('isValid Sherlock', () => {
it("should return 'YES' for string with equal frequencies", () => {
expect(isValid('aabbcc')).toBe('YES')
})

it("should return 'YES' when one character can be removed to equalize frequencies", () => {
expect(isValid('aabbc')).toBe('YES')
})

it("should return 'NO' when more than one removal is needed", () => {
expect(isValid('aabbcd')).toBe('NO')
})

it("should return 'YES' when only one character has freq=1", () => {
expect(isValid('aaabbbcccd')).toBe('YES')
})

it("should return 'NO' when no valid removal can equalize frequencies", () => {
expect(isValid('aabbccddeefghi')).toBe('NO')
})

it("should return 'YES' for a string with all same character", () => {
expect(isValid('aaaa')).toBe('YES')
})

it("should return 'YES' for a single character", () => {
expect(isValid('z')).toBe('YES')
})
})