Skip to content

Commit b6bc426

Browse files
committedJan 23, 2024
Add: Exercise 1207. Unique Number of Occurrences
1 parent 1de98dc commit b6bc426

File tree

4 files changed

+142
-0
lines changed

4 files changed

+142
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# 1657. Determine if Two Strings Are Close
2+
Two strings are considered close if you can attain one from the other using the following
3+
operations:
4+
5+
**Operation 1**: Swap any two existing characters.
6+
For example, `abcde` -> `aecdb`
7+
8+
**Operation 2**: Transform every occurrence of one existing character into another existing character, and do the same with the other character.
9+
For example, `aacabb` -> `bbcbaa` (all a's turn into b's, and all b's turn into a's)
10+
You can use the operations on either string as many times as necessary.
11+
12+
Given two strings, `word1` and `word2`, return `true` if `word1` and `word2` are close, and `false` otherwise.
13+
14+
## Examples
15+
16+
### Example 1:
17+
Input: `word1` = "abc", `word2` = "bca"
18+
Output: `true`
19+
Explanation: You can attain `word2` from `word1` in 2 operations.
20+
Apply Operation 1: "abc" -> "acb"
21+
Apply Operation 1: "acb" -> "bca"
22+
23+
### Example 2:
24+
Input: `word1` = "a", `word2` = "aa"
25+
Output: `false`
26+
Explanation: It is impossible to attain `word2` from `word1`, or vice versa, in any number of operations.
27+
28+
### Example 3:
29+
Input: `word1` = "cabbba", `word2` = "abbccc"
30+
Output: `true`
31+
Explanation: You can attain `word2` from `word1` in 3 operations.
32+
Apply Operation 1: "cabbba" -> "caabbb"
33+
Apply Operation 2: "caabbb" -> "baaccc"
34+
Apply Operation 2: "baaccc" -> "abbccc"
35+
36+
## Constraints
37+
- 1 <= `word1.length`, `word2.length` <= 10^5
38+
- `word1` and `word2` contain only lowercase English letters.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @param {string} word1
3+
* @param {string} word2
4+
* @return {boolean}
5+
*/
6+
var closeStrings = function(word1, word2) {
7+
// Edge case: different lengths
8+
if (word1.length !== word2.length) {
9+
return false
10+
}
11+
12+
// Obtain letter maps and sets
13+
const word1FreqMap = {}
14+
const word2FreqMap = {}
15+
const word1LetterSet = new Set()
16+
const word2LetterSet = new Set()
17+
let word1Freqs = []
18+
let word2Freqs = []
19+
20+
for (let i = 0; i < word1.length; i++) {
21+
word1FreqMap.hasOwnProperty(word1[i]) ? word1FreqMap[word1[i]]++ : word1FreqMap[word1[i]] = 1
22+
word2FreqMap.hasOwnProperty(word2[i]) ? word2FreqMap[word2[i]]++ : word2FreqMap[word2[i]] = 1
23+
}
24+
25+
// Let's create the sets
26+
for (const key in word1FreqMap) {
27+
word1LetterSet.add(key)
28+
word1Freqs.push(word1FreqMap[key])
29+
}
30+
for (const key in word2FreqMap) {
31+
word2LetterSet.add(key)
32+
word2Freqs.push(word2FreqMap[key])
33+
}
34+
35+
// Let's compare sizes
36+
if (word1LetterSet.size !== word2LetterSet.size) {
37+
return false
38+
}
39+
40+
// Let's iterate and compare letters and frequencies
41+
word1LetterSet.forEach((letter) => {
42+
if (!word2LetterSet.has(letter)) return false
43+
word2LetterSet.delete(letter)
44+
})
45+
46+
if (word2LetterSet.size !== 0) return false
47+
48+
word1Freqs = word1Freqs.sort()
49+
word2Freqs = word2Freqs.sort()
50+
51+
// There should be the same frequencies in order of two strings to be close
52+
for (let i = 0; i < word1Freqs.length; i++) {
53+
if (word1Freqs[i] !== word2Freqs[i]) return false
54+
}
55+
56+
return true
57+
};
58+
59+
var output = closeStrings('abbzzca', 'babzzcz')
60+
61+
module.exports = closeStrings
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "1657-determine-if-two-strings-are-close",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"start": "node index.js",
8+
"debug": "node --inspect-brk index.js",
9+
"test": "node test.js"
10+
},
11+
"keywords": [],
12+
"author": "",
13+
"license": "ISC"
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const assert = require('assert')
2+
const closeStrings = require('./index')
3+
4+
const tests = [
5+
{
6+
word1: 'abc',
7+
word2: 'bca',
8+
expectedOutput: true
9+
},
10+
{
11+
word1: 'a',
12+
word2: 'aa',
13+
expectedOutput: false
14+
},
15+
{
16+
word1: 'cabbba',
17+
word2: 'abbccc',
18+
expectedOutput: true
19+
},
20+
{
21+
word1: 'abbzzca',
22+
word2: 'babzzcz',
23+
expectedOutput: false
24+
},
25+
]
26+
27+
for (const t of tests) {
28+
assert.strictEqual(closeStrings(t.word1, t.word2), t.expectedOutput)
29+
}

0 commit comments

Comments
 (0)
Please sign in to comment.