You are given an integer array `nums`

of length `n`

where `nums`

is a permutation of the numbers in the range `[0, n - 1]`

.

You should build a set `s[k] = {nums[k], nums[nums[k]], nums[nums[nums[k]]], ... }`

subjected to the following rule:

The first element in

`s[k]`

starts with the element`nums[k]`

.The next element in

`s[k]`

should be`nums[nums[k]]`

, and then`nums[nums[nums[k]]]`

, and so on.We stop adding elements before a duplicate element occurs in

`s[k]`

.

Return the length of the longest set `s[k]`

.

```
Input: nums = [5,4,0,3,1,6,2]
Output: 4
Explanation:
nums[0] = 5, nums[1] = 4, nums[2] = 0, nums[3] = 3, nums[4] = 1, nums[5] = 6, nums[6] = 2.
One of the longest sets s[k]:
s[0] = {nums[0], nums[5], nums[6], nums[2]} = {5, 6, 2, 0}
```

```
Input: nums = [0,1,2]
Output: 1
```

`1 <= nums.length <= 10^5`

.`0 <= nums[i] < nums.length`

.All the values of

`nums`

are unique.

A permutation is a one-to-one mapping from a set of integers to itself.

The permutation on the set `nums`

in this problem is defined by the mapping `i -> nums[i]`

. For instance in Example 1, the permutation is defined as following:

```
0 -> 5,
1 -> 4,
2 -> 0,
3 -> 3,
4 -> 1,
5 -> 6,
6 -> 2.
```

You can always rearrange the definition of a permutation into groups of cyclic chains (factors).

```
0 -> 5, 5 -> 6, 6 -> 2, 2 -> 0,
1 -> 4, 4 -> 1,
3 -> 3
```

The set `s[k]`

in this problem is such a chain. In mathematics, it is called a *cycle*; because the chain `(0, 5, 6, 2)`

is considered the same as `(5, 6, 2, 0)`

, `(6, 2, 0, 5)`

or `(2, 0, 5, 6)`

in Example 1.

Assume you have used some elements of the array `nums`

to construct some cycles. To construct another one, you should start with the unused elements.

The problem leads to finding the longest cycle of a given permutation.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int arrayNesting(vector<int>& nums) {
int maxLen(0);
vector<bool> visited(nums.size());
for (auto i : nums) {
if (visited[i]) {
continue;
}
int len(0);
while (!visited[i]) {
visited[i] = true;
i = nums[i];
len++;
}
maxLen = max(len, maxLen);
}
return maxLen;
}
int main() {
vector<int> nums = {5,4,0,3,1,6,2};
cout << arrayNesting(nums) << endl;
nums = {0,1,2};
cout << arrayNesting(nums) << endl;
nums = {0,2,1};
cout << arrayNesting(nums) << endl;
nums = {2,0,1};
cout << arrayNesting(nums) << endl;
}
```

```
Output:
4
1
2
3
```

Runtime:

`O(N)`

, where`N = nums.length`

.Extra space: much less than

`O(N)`

since`vector<bool>`

is optimized for space efficiency.

*Thanks for reading. Feel free to share your thought about my content and check out my FREE book* *10 Classic Coding Challenges**.*

*What is your approach? The problem was picked from* *leetcode.com**. You can submit your solution in any programming language and check the performance.*

Given two version numbers, `version1`

and `version2`

, compare them.

Version numbers consist of one or more revisions joined by a dot `'.'`

. Each revision consists of digits and may contain leading zeros. Every revision contains at least one character. Revisions are 0-indexed from left to right, with the leftmost revision being revision 0, the next revision being revision 1, and so on.

For example `2.5.33`

and `0.1`

are valid version numbers.

To compare version numbers, compare their revisions in left-to-right order. Revisions are compared using their integer value ignoring any leading zeros. This means that revisions `1`

and `001`

are considered equal. If a version number does not specify a revision at an index, then treat the revision as `0`

. For example, version `1.0`

is less than version `1.1`

because their revision 0s are the same, but their revision 1s are `0`

and `1`

respectively, and `0 < 1`

.

Return the following:

If

`version1 < version2`

, return`-1`

.If

`version1 > version2`

, return`1`

.Otherwise, return

`0`

.

```
Input: version1 = "1.01", version2 = "1.001"
Output: 0
Explanation: Ignoring leading zeroes, both "01" and "001" represent the same integer "1".
```

```
Input: version1 = "1.0", version2 = "1.0.0"
Output: 0
Explanation: version1 does not specify revision 2, which means it is treated as "0".
```

```
Input: version1 = "0.1", version2 = "1.1"
Output: -1
Explanation: version1's revision 0 is "0", while version2's revision 0 is "1". 0 < 1, so version1 < version2.
```

`1 <= version1.length, version2.length <= 500`

.`version1`

and`version2`

only contain digits and`'.'`

.`version1`

and`version2`

are valid version numbers.All the given revisions in

`version1`

and`version2`

can be stored in a 32-bit integer.

Each version can be considered as an array of revisions.

```
version = revisions[0].revisions[1].revisions[2]....
```

The problem is to compare each `revisions[i]`

between two versions.

For example, `revisions[0]`

of `version1`

is less than of `version2`

in Example 3. So the result is `-1`

.

All `revisions[i]`

of `version1`

and `version2`

are equal in Example 1. So the result is `0`

.

The number of revisions between the versions might not be equal (like in Example 2).

If all revisions of the shorter version are equal to the corresponding revisions of the longer one, the version having extra revisions and there exists a non-zero revision among them is the bigger one. Otherwise, the two versions are equal.

```
#include <iostream>
#include <vector>
#include <string>
#include <numeric>
using namespace std;
vector<int> toVector(const string& version) {
vector<int> revisions;
string revision;
for (char c : version) {
if (c != '.') {
revision += c;
} else {
revisions.push_back(stoi(revision));
revision = "";
}
}
revisions.push_back(stoi(revision));
return revisions;
}
int compareVersion(string version1, string version2) {
vector<int> revisions1 = toVector(version1);
vector<int> revisions2 = toVector(version2);
int i = 0;
while (i < revisions1.size() && i < revisions2.size()) {
if (revisions1[i] < revisions2[i]) {
return -1;
} else if (revisions1[i] > revisions2[i]) {
return 1;
}
i++;
}
int remain1 = accumulate(revisions1.begin() + i, revisions1.end(), 0);
int remain2 = accumulate(revisions2.begin() + i, revisions2.end(), 0);
if (remain1 < remain2) {
return -1;
} else if (remain1 > remain2) {
return 1;
}
return 0;
}
int main() {
cout << compareVersion("1.01", "1.001") << endl;
cout << compareVersion("1.0", "1.0.0") << endl;
cout << compareVersion("0.1", "1.1") << endl;
}
```

```
Output:
0
0
-1
```

Runtime:

`O(N)`

where`N = max(version1.length, version2.length)`

.Extra space:

`O(N)`

.

`std::stoi(string)`

is used to convert a`string`

to an`int`

. It ignores the leading zeros for you.`std::accumulate(firstIter, lastIter, initValue)`

is used to compute the sum of a container.

*Thanks for reading. Feel free to share your thought about my content.*

*What is your approach? The problem was picked from* *leetcode.com**. You can submit your solution in any programming language and check the performance.*

Given an array `intervals`

where `intervals[i] = [li, ri]`

represent the interval `[li, ri)`

, remove all intervals that are covered by another interval in the list.

The interval `[a, b)`

is covered by the interval `[c, d)`

if and only if `c <= a`

and `b <= d`

.

Return the number of remaining intervals.

```
Input: intervals = [[1,4],[3,6],[2,8]]
Output: 2
Explanation: Interval [3,6] is covered by [2,8], therefore it is removed.
```

```
Input: intervals = [[1,4],[2,3]]
Output: 1
```

`1 <= intervals.length <= 1000`

.`intervals[i].length == 2`

.`0 <= li <= ri <= 10^5`

.All the given intervals are unique.

For each interval `i`

, find if any other interval `j`

such that `j`

covers `i`

or `i`

covers `j`

then remove the smaller one from `intervals`

.

For `intervals = [[1,4],[3,6],[2,8]]`

.

With interval

`i = [1,4]`

, there is no other interval`j`

such that covers`i`

or`j`

covers`i`

.With interval

`i = [3,6]`

, there is interval`j = [2,8]`

convering`i`

. Remove`[3,6]`

from`intervals`

.

Final `intervals = [[1,4],[2,8]]`

.

```
#include <vector>
#include <iostream>
using namespace std;
inline bool isCovered(vector<int>& i, vector<int>& j) {
return j[0] <= i[0] && i[1] <= j[1];
}
int removeCoveredIntervals(vector<vector<int>>& intervals) {
int i = 0;
while (i < intervals.size() - 1) {
int j = i + 1;
bool erase_i = false;
while (j < intervals.size()) {
if (isCovered(intervals[i], intervals[j])) {
intervals.erase(intervals.begin() + i);
erase_i = true;
break;
} else if (isCovered(intervals[j], intervals[i])) {
intervals.erase(intervals.begin() + j);
} else {
j++;
}
}
if (!erase_i) {
i++;
}
}
return intervals.size();
}
int main() {
vector<vector<int>> intervals{{1,4},{3,6},{2,8}};
cout << removeCoveredIntervals(intervals) << endl;
intervals = {{1,4},{2,3}};
cout << removeCoveredIntervals(intervals) << endl;
}
```

```
Output:
2
1
```

Runtime:

`O(N^3)`

, where`N = intervals.length`

.Extra space:

`O(1)`

.

You might know how to look up words in a dictionary.

The word `apple`

appears before `candy`

in the dictionary because the starting letter `a`

of `apple`

appears before `c`

of `candy`

in the English alphabet.

And `apple`

appears after `animal`

since the next letter `p`

appears after `n`

.

The C++ Standard Library uses that dictionary order to compare two `std::vector`

s.

Rewriting `intervals = [[1,4],[3,6],[2,8]]`

in dictionary order you get `intervals = [[1,4],[2,8],[3,6]]`

. In this order, the left bounds of the `intervals`

are sorted first.

If `intervals`

is sorted like that, you can avoid bruteforce in Solution 1 by a simpler algorithm.

**Check if each interval** `i`

covers or is covered by some of the previous ones.

Remember that the left bound of interval `i`

is always bigger than or equal to all left bounds of the previous ones. So,

`i`

is covered by some previous interval if the right bound of`i`

is less than some of the right bounds before.Otherwise

`i`

can only cover its exact previous one that has the same left bound.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int removeCoveredIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end());
int count = 0;
int maxRight = -1;
int preLeft = -1;
for (auto& i : intervals) {
if (i[1] <= maxRight) { // i is covered by some previous interval
count++;
} else if (i[0] == preLeft) { // i covers its exact previous one
count++;
} else {
preLeft = i[0];
}
maxRight = max(maxRight, i[1]);
}
return intervals.size() - count;
}
int main() {
vector<vector<int>> intervals{{1,4},{3,6},{2,8}};
cout << removeCoveredIntervals(intervals) << endl;
intervals = {{1,4},{2,3}};
cout << removeCoveredIntervals(intervals) << endl;
}
```

```
Output:
2
1
```

Runtime:

`O(NlogN)`

, where`N = intervals.length`

.Extra space:

`O(1)`

.

- Two
`std::vector`

s can be compared using the dictionary order.

*Thanks for reading. Feel free to share your thought about my content.*

*What is your approach? The problem was picked from* *leetcode.com**. You can submit your solution in any programming language and check the performance.*

Given two strings `s`

and `t`

, return `true`

if `t`

is an anagram of `s`

, and `false`

otherwise.

An ** Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

```
Input: s = "anagram", t = "nagaram"
Output: true
```

```
Input: s = "rat", t = "car"
Output: false
```

`1 <= s.length, t.length <= 5 * 10^4`

.`s`

and`t`

consist of lowercase English letters.

**Follow up**: What if the inputs contain Unicode characters? How would you adapt your solution to such a case?

`s`

and `t`

into a sorted string```
#include <iostream>
#include <algorithm>
using namespace std;
bool isAnagram(string s, string t) {
if (s.length() != t.length()) {
return false;
}
sort(s.begin(), s.end());
sort(t.begin(), t.end());
return s == t;
}
int main() {
cout << isAnagram("anagram", "nagaram") << endl;
cout << isAnagram("rat", "car") << endl;
}
```

```
Output:
1
0
```

Runtime:

`O(NlogN)`

, where`N = s.length`

.Extra space:

`O(1)`

.

```
#include <iostream>
using namespace std;
bool isAnagram(string s, string t) {
if (s.length() != t.length()) {
return false;
}
int alphabet[26];
for (int i = 0; i < 26; i++) {
alphabet[i] = 0;
}
for (char& c : s) {
alphabet[c - 'a']++;
}
for (char& c : t) {
alphabet[c - 'a']--;
if (alphabet[c - 'a'] < 0) {
return false;
}
}
return true;
}
int main() {
cout << isAnagram("anagram", "nagaram") << endl;
cout << isAnagram("rat", "car") << endl;
}
```

```
Output:
1
0
```

Runtime:

`O(N)`

, where`N = s.length`

.Extra space:

`O(1)`

.

In the solutions above, the array `alphabet`

represents 26 letters `'a'`

to `'z'`

. You can generalize to allow it contains any character by using a map.

```
#include <iostream>
#include <unordered_map>
using namespace std;
bool isAnagram(string s, string t) {
if (s.length() != t.length()) {
return false;
}
unordered_map<char, int> alphabet;
for (char& c : s) {
alphabet[c]++;
}
for (char& c : t) {
alphabet[c]--;
if (alphabet[c] < 0) {
return false;
}
}
return true;
}
int main() {
cout << isAnagram("anagam", "nagaam") << endl;
cout << isAnagram("rat", "car") << endl;
}
```

```
Output:
1
0
```

Runtime:

`O(N)`

, where`N = s.length`

.Extra space:

`O(1)`

.

An array of 26 integers can represent the English alphabet.

Counting the appearances can help identify if a word is a permutation of another.

You can use a map to count the appearances of the letters of a word.

*Thanks for reading. Feel free to share your thought about my content.*

*What is your approach? The problem was picked from* *leetcode.com**. You can submit your solution in any programming language and check the performance.*

Given an array of integers `temperatures`

representing the daily temperatures, return an array `answer`

such that `answer[i]`

is the number of days you have to wait after the `i-th`

day to get a warmer temperature. If there is no future day for which this is possible, keep `answer[i] = 0`

instead.

```
Input: temperatures = [73,74,75,71,69,72,76,73]
Output: [1,1,4,2,1,1,0,0]
```

```
Input: temperatures = [30,40,50,60]
Output: [1,1,1,0]
```

```
Input: temperatures = [30,60,90]
Output: [1,1,0]
```

`1 <= temperatures.length <= 10^5`

.`30 <= temperatures[i] <= 100`

.

For each `temperatures[i]`

, find the closest `temperatures[j]`

with `j > i`

such that `temperatures[j] > temperatures[i]`

, then `answer[i] = j - i`

. If not found, `answer[i] = 0`

.

For `temperatures = [73,74,75,71,69,72,76,73]`

:

`answer[0] = 1`

since the next day is warmer (`74 > 73`

).`answer[1] = 1`

since the next day is warmer (`75 > 74`

).`answer[2] = 4`

since only after`4`

days it is warmer (`76 > 75`

).And so on.

```
#include <vector>
#include <iostream>
using namespace std;
vector<int> dailyTemperatures(vector<int>& temperatures) {
vector<int> answer(temperatures.size());
for (int i = 0; i < temperatures.size(); i++) {
answer[i] = 0;
for (int j = i + 1; j < temperatures.size(); j++) {
if (temperatures[j] > temperatures[i]) {
answer[i] = j - i;
break;
}
}
}
return answer;
}
void print(vector<int>& answer) {
cout << "[";
for (auto& v : answer ) {
cout << v << ",";
}
cout << "]\n";
}
int main() {
vector<int> temperatures{73,74,75,71,69,72,76,73};
auto answer = dailyTemperatures(temperatures);
print(answer);
temperatures = {30,40,50,60};
answer = dailyTemperatures(temperatures);
print(answer);
temperatures = {30,60,90};
answer = dailyTemperatures(temperatures);
print(answer);
}
```

```
Output:
[1,1,4,2,1,1,0,0,]
[1,1,1,0,]
[1,1,0,]
```

Runtime:

`O(N^2)`

, where`N = temperatures.length`

.Extra space:

`O(1)`

.

The straightforward solution above is easy to understand, but the complexity is `O(N^2)`

.

The way starting from the first day to the last day does not make use of the knowledge of the `answer[i]`

values.

The value

`answer[i] > 0`

tells you that`temperatures[i + answer[i]]`

is the next temperature that is warmer than`temperatures[i]`

.The value

`answer[i] = 0`

tells you that there is no warmer temperature than`temperatures[i]`

.

When computing `answer[i]`

in the reversed order, you can use that knowledge more efficiently.

Suppose you already know the future values `answer[j]`

. To compute an older value `answer[i]`

with `i < j`

, you need only to compare `temperatures[i]`

with `temperatures[i + 1]`

and its **chain** of warmer temperatures.

For `temperatures = [73,74,75,71,69,72,76,73]`

.

Suppose you have computed all `answer[j]`

with `j > 2`

, `answer = [?,?,?,2,1,1,0,0]`

.

To compute `answer[i = 2]`

for `temperatures[2] = 75`

, you need to compare it with

`temperatures[3] = 71 (< 75)`

. Go to the next warmer temperature than`temperatures[3]`

, which is`temperatures[3 + answer[3]] = temperatures[3 + 2]`

.`temperatures[5] = 72 (< 75)`

. Go to the next warmer temperature than`temperatures[5]`

, which is`temperatures[5 + answer[5]] = temperatures[5 + 1]`

.`temperatures[6] = 76 (> 75)`

. Stop.`answer[i = 2] = j - i = 6 - 2 = 4`

.

```
#include <vector>
#include <iostream>
using namespace std;
vector<int> dailyTemperatures(vector<int>& temperatures) {
vector<int> answer(temperatures.size(), 0);
for (int i = temperatures.size() - 2; i >= 0 ; i--) {
int j = i + 1;
while (j < temperatures.size() && temperatures[j] <= temperatures[i]) {
if (answer[j] > 0) { // there is some temperature bigger than temperatures[j]
j += answer[j]; // go to that value
} else {
j = temperatures.size();
}
}
if (j < temperatures.size()) {
answer[i] = j - i;
}
}
return answer;
}
void print(vector<int>& answer) {
cout << "[";
for (auto& v : answer ) {
cout << v << ",";
}
cout << "]\n";
}
int main() {
vector<int> temperatures{73,74,75,71,69,72,76,73};
auto answer = dailyTemperatures(temperatures);
print(answer);
temperatures = {30,40,50,60};
answer = dailyTemperatures(temperatures);
print(answer);
temperatures = {30,60,90};
answer = dailyTemperatures(temperatures);
print(answer);
}
```

```
Output:
[1,1,4,2,1,1,0,0,]
[1,1,1,0,]
[1,1,0,]
```

Worse cases for the `while`

loop are when most `temperatures[j]`

in their chain are cooler than `temperatures[i]`

.

In these cases, the resulting `answer[i]`

will be either `0`

or a big value `j - i`

. Those extreme values give you a huge knowledge when computing `answer[i]`

for other older days `i`

.

The value `0`

would help the `while`

loop terminates very soon. On the other hand, the big value `j - i`

would help the `while`

loop skips the days `j`

very quickly.

Runtime:

`O(NlogN)`

, where`N = temperatures.length`

.Extra space:

`O(1)`

.

In some computations, you could improve the performance by using the knowledge of the results you have computed.

In this particular problem, it can be achieved by doing it in the reversed order.

*Thanks for reading. Feel free to share your thought about my content.*

*What is your approach? The problem was picked from* *leetcode.com**. You can submit your own solution in any programming language and check the performance there.*

Roman numerals are represented by seven symbols: `I`

, `V`

, `X`

, `L`

, `C`

, `D`

, and `M`

.

```
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
```

For example, `2`

is written as `II`

in Roman numeral, just two ones added together. `12`

is written as `XII`

, which is simply `X + II`

. The number `27`

is written as `XXVII`

, which is `XX + V + II`

.

Roman numerals are usually written from largest to smallest and from left to right. However, the numeral for four is not `IIII`

. Instead, the number four is written as `IV`

. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as `IX`

. There are six instances where subtraction is used:

`I`

can be placed before`V`

(`5`

) and`X`

(`10`

) to make`4`

and`9`

.`X`

can be placed before`L`

(`50`

) and`C`

(`100`

) to make`40`

and`90`

.`C`

can be placed before`D`

(`500`

) and`M`

(`1000`

) to make`400`

and`900`

.

Given a Roman numeral, convert it to an integer.

```
Input: s = "III"
Output: 3
Explanation: III = 3.
```

```
Input: s = "LVIII"
Output: 58
Explanation: L = 50, V = 5, III = 3.
```

```
Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
```

`1 <= s.length <= 15`

.`s`

contains only the characters`'I'`

,`'V'`

,`'X'`

,`'L'`

,`'C'`

,`'D'`

,`'M'`

.It is guaranteed that

`s`

is a valid Roman numeral in the range`[1, 3999]`

.

And to treat the subtraction cases easier, you can iterate the string `s`

backward.

```
#include <iostream>
#include <unordered_map>
using namespace std;
int romanToInt(string s) {
unordered_map<char, int> value = {
{'I', 1},
{'V', 5},
{'X', 10},
{'L', 50},
{'C', 100},
{'D', 500},
{'M', 1000}
};
int i = s.length() - 1;
int result = value[s[i--]];
while (i >= 0) {
if (value[s[i]] < value[s[i+1]]) {
result -= value[s[i--]];
} else {
result += value[s[i--]];
}
}
return result;
}
int main() {
cout << romanToInt("III") << endl;
cout << romanToInt("LVIII") << endl;
cout << romanToInt("MCMXCIV") << endl;
}
```

```
Output:
3
58
1994
```

Runtime:

`O(N)`

where`N = s.length`

.Extra space:

`O(1)`

(the map`value`

is very small).

The problem is about encoding/decoding between a string and an integer, you could use an unordered_map here.

This is a very interesting problem since it is about history and mathematics. You can read more about it on Wikipedia.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

*What is your solution to this problem? Check the correction and the performance of your code at* *leetcode.com**.*

The *Fibonacci* numbers, commonly denoted `F(n)`

form a sequence, called the Fibonacci sequence, such that each number is the sum of the two preceding ones, starting from `0`

and `1`

. That is,

```
F(0) = 0, F(1) = 1
F(n) = F(n - 1) + F(n - 2), for n > 1.
```

Given `n`

, calculate `F(n)`

.

```
Input: n = 2
Output: 1
Explanation: F(2) = F(1) + F(0) = 1 + 0 = 1.
```

```
Input: n = 3
Output: 2
Explanation: F(3) = F(2) + F(1) = 1 + 1 = 2.
```

```
Input: n = 4
Output: 3
Explanation: F(4) = F(3) + F(2) = 2 + 1 = 3.
```

`0 <= n <= 30`

.

```
#include <iostream>
int fib(int n) {
if (n <= 1) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
int main() {
std::cout << fib(2) << std::endl;
std::cout << fib(3) << std::endl;
std::cout << fib(4) << std::endl;
}
```

```
Output:
1
2
3
```

Runtime:

`O(2^n)`

.Extra space:

`O(2^n)`

.

```
#include <iostream>
#include <vector>
int fib(int n) {
if (n <= 1) {
return n;
}
std::vector<int> f(n + 1);
f[0] = 0;
f[1] = 1;
for (int i = 2; i <= n; i++) {
f[i] = f[i - 1] + f[i - 2];
}
return f[n];
}
int main() {
std::cout << fib(2) << std::endl;
std::cout << fib(3) << std::endl;
std::cout << fib(4) << std::endl;
}
```

```
Output:
1
2
3
```

Runtime:

`O(n)`

.Extra space:

`O(n)`

.

```
#include <iostream>
#include <vector>
int fib(int n) {
if (n <= 1) {
return n;
}
int f0 = 0;
int f1 = 1;
for (int i = 2; i <= n; i++) {
int f2 = f1 + f0;
f0 = f1;
f1 = f2;
}
return f1;
}
int main() {
std::cout << fib(2) << std::endl;
std::cout << fib(3) << std::endl;
std::cout << fib(4) << std::endl;
}
```

```
Output:
1
2
3
```

Runtime:

`O(n)`

.Extra space:

`O(1)`

.

*You can try to solve this problem by yourself at* *https://leetcode.com/problems/fibonacci-number/*

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Design a HashSet without using any built-in hash table libraries.

Implement `MyHashSet`

class:

`void add(key)`

Inserts the value`key`

into the HashSet.`bool contains(key)`

Returns whether the value`key`

exists in the HashSet or not.`void remove(key)`

Removes the value`key`

in the HashSet. If`key`

does not exist in the HashSet, do nothing.

```
Input
["MyHashSet", "add", "add", "contains", "contains", "add", "contains", "remove", "contains"]
[[], [1], [2], [1], [3], [2], [2], [2], [2]]
Output
[null, null, null, true, false, null, true, null, false]
Explanation
MyHashSet myHashSet = new MyHashSet();
myHashSet.add(1); // set = [1]
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(1); // return True
myHashSet.contains(3); // return False, (not found)
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(2); // return True
myHashSet.remove(2); // set = [1]
myHashSet.contains(2); // return False, (already removed)
```

`0 <= key <= 10^6`

.At most

`10^4`

calls will be made to`add`

,`remove`

, and`contains`

.

The simplest way is using a container to store the keys so you can identify if a key belongs to the HashSet or not.

```
#include <iostream>
#include <vector>
using namespace std;
class MyHashSet {
vector<int> _v;
public:
MyHashSet() {
}
void add(int key) {
if (!contains(key)) {
_v.push_back(key);
}
}
void remove(int key) {
auto it = _v.begin();
while (it != _v.end()) {
if (*it == key) {
_v.erase(it);
return;
} else {
it++;
}
}
}
bool contains(int key) {
for (int a : _v) {
if (a == key) {
return true;
}
}
return false;
}
};
int main() {
MyHashSet m;
m.add(1);
m.add(2);
cout << m.contains(1) << endl;
cout << m.contains(3) << endl;
m.add(2);
cout << m.contains(2) << endl;
m.remove(2);
cout << m.contains(2) << endl;
}
```

```
Output:
1
0
1
0
```

Runtime:

`O(N)`

for all methods, where`N`

is the number of values in the HashSet.Extra space:

`O(N)`

.

In this problem, the HashSet does not have anything other than methods `add`

, `remove`

and `contains`

, which only check whether a `key`

exists in it or not.

With this purpose you can simply mark the keys without storing them.

```
#include <iostream>
#include <vector>
using namespace std;
class MyHashSet {
vector<bool> _v;
public:
MyHashSet() : _v(1000001, false){
}
void add(int key) {
_v[key] = true;
}
void remove(int key) {
_v[key] = false;
}
bool contains(int key) {
return _v[key];
}
};
int main() {
MyHashSet m;
m.add(1);
m.add(2);
cout << m.contains(1) << endl;
cout << m.contains(3) << endl;
m.add(2);
cout << m.contains(2) << endl;
m.remove(2);
cout << m.contains(2) << endl;
}
```

```
Output:
1
0
1
0
```

Runtime:

`O(1)`

.Extra space:

`O(1)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

You are implementing a program to use as your calendar. We can add a new event if adding the event will not cause a double booking.

A double booking happens when two events have some non-empty intersection (i.e., some moment is common to both events.).

The event can be represented as a pair of integers `start`

and `end`

that represents a booking on the half-open interval `[start, end)`

, the range of real numbers `x`

such that `start <= x < end`

.

Implement the `MyCalendar`

class:

`MyCalendar()`

Initializes the calendar object.`boolean book(int start, int end)`

Returns`true`

if the event can be added to the calendar successfully without causing a double booking. Otherwise, return`false`

and do not add the event to the calendar.

```
Input
["MyCalendar", "book", "book", "book"]
[[], [10, 20], [15, 25], [20, 30]]
Output
[null, true, false, true]
Explanation
MyCalendar myCalendar = new MyCalendar();
myCalendar.book(10, 20); // return True
myCalendar.book(15, 25); // return False. It can not be booked because time 15 is already booked by another event.
myCalendar.book(20, 30); // return True, The event can be booked, as the first event takes every time less than 20, but not including 20.
```

`0 <= start < end <= 10^9`

.At most

`1000`

calls will be made to book.

You can store the booked events in a vector and check the intersection condition whenever you add a new event.

```
#include <iostream>
#include <vector>
using namespace std;
class MyCalendar {
private:
vector<pair<int,int>> _events;
public:
MyCalendar() {}
bool book(int start, int end) {
for (auto& e : _events) {
if (!(e.second <= start || end <= e.first)) {
return false;
}
}
_events.push_back({start, end});
return true;
}
};
int main() {
MyCalendar c;
std::cout << c.book(10, 20) << std::endl;
std::cout << c.book(15, 25) << std::endl;
std::cout << c.book(20, 30) << std::endl;
}
```

```
Output:
1
0
1
```

Runtime:

`O(N)`

, where`N = _events.length`

.Extra space:

`O(N)`

.

Since the events have no intersection, they can be sorted. You can also consider two events to be the same if they intersect.

With that in mind, you can use `std::set`

to store the sorted unique events.

```
#include <iostream>
#include <set>
using namespace std;
using Event = pair<int,int>;
struct EventCmp {
bool operator()(const Event& lhs, const Event& rhs) const {
return lhs.second <= rhs.first;
}
};
class MyCalendar {
private:
set<Event, EventCmp> _events;
public:
MyCalendar() {}
bool book(int start, int end) {
auto result = _events.insert({start, end});
return result.second;
}
};
int main() {
MyCalendar c;
std::cout << c.book(10, 20) << std::endl;
std::cout << c.book(15, 25) << std::endl;
std::cout << c.book(20, 30) << std::endl;
}
```

```
Output:
1
0
1
```

Runtime:

`O(logN)`

, where`N = _events.length`

.Extra space:

`O(N)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

There is an undirected graph with `n`

nodes, where each node is numbered between `0`

and `n - 1`

. You are given a 2D array `graph`

, where `graph[u]`

is an array of nodes that node `u`

is adjacent to. More formally, for each `v`

in `graph[u]`

, there is an undirected edge between node `u`

and node `v`

. The graph has the following properties:

There are no self-edges (

`graph[u]`

does not contain`u`

).There are no parallel edges (

`graph[u]`

does not contain duplicate values).If

`v`

is in`graph[u]`

, then`u`

is in`graph[v]`

(the graph is undirected).The graph may not be connected, meaning there may be two nodes

`u`

and`v`

such that there is no path between them.

A graph is **bipartite** if the nodes can be partitioned into two independent sets `A`

and `B`

such that every edge in the graph connects a node in set `A`

and a node in set `B`

.

Return `true`

if and only if it is bipartite.

```
Input: graph = [[1,2,3],[0,2],[0,1,3],[0,2]]
Output: false
Explanation: There is no way to partition the nodes into two independent sets such that every edge connects a node in one and a node in the other.
```

```
Input: graph = [[1,3],[0,2],[1,3],[0,2]]
Output: true
Explanation: We can partition the nodes into two sets: {0, 2} and {1, 3}.
```

`graph.length == n`

.`1 <= n <= 100`

.`0 <= graph[u].length < n`

.`0 <= graph[u][i] <= n - 1`

.`graph[u]`

does not contain`u`

.All the values of

`graph[u]`

are unique.If

`graph[u]`

contains`v`

, then`graph[v]`

contains`u`

.

You could color the nodes in set A with one color and those in B with another color. Then two ends of every edge have different colors.

Now you can use the DFS algorithm to color each connected component of the graph.

During the traversal, if there is an edge having the same color at two ends, then return `false`

.

```
#include <vector>
#include <iostream>
using namespace std;
bool isBipartite(vector<vector<int>>& graph) {
vector<int> color(graph.size(), 0);
for (int i = 0; i < graph.size(); i++) {
if (color[i] != 0) continue;
vector<int> s;
s.push_back(i);
color[i] = 1;
while (!s.empty()) {
int u = s.back();
s.pop_back();
for (int v : graph[u]) {
if (color[v] == 0) {
color[v] = -color[u];
s.push_back(v);
} else if (color[v] == color[u]) {
return false;
}
}
}
}
return true;
}
int main() {
vector<vector<int>> graph{{1,2,3},{0,2},{0,1,3},{0,2}};
cout << isBipartite(graph) << endl;
graph = {{1,3},{0,2},{1,3},{0,2}};
cout << isBipartite(graph) << endl;
}
```

```
Output:
0
1
```

Runtime:

`O(n)`

, where`n = graph.length`

.Extra space:

`O(n)`

.

This is the non-recursive implementation of DFS algorithm where you could use the stack data structure to avoid the recursion.

The stack's methods needed in the DFS algorithm are only

`push`

and`pop`

. There are similar ones in`std::vector`

, which are`push_back`

and`pop_back`

which you could use well.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given two strings `s`

and `t`

, return `true`

if they are equal when both are typed into empty text editors. `'#'`

means a backspace character.

Note that after backspacing an empty text, the text will continue empty.

```
Input: s = "ab#c", t = "ad#c"
Output: true
Explanation: Both s and t become "ac".
```

```
Input: s = "ab##", t = "c#d#"
Output: true
Explanation: Both s and t become "".
```

```
Input: s = "a#c", t = "b"
Output: false
Explanation: s becomes "c" while t becomes "b".
```

`1 <= s.length, t.length <= 200`

.`s`

and`t`

only contain lowercase letters and`'#'`

characters.

**Follow up**: Can you solve it in `O(n)`

time and `O(1)`

space?

`stack`

's behaviors```
#include <iostream>
#include <vector>
using namespace std;
string cleanString(string &s) {
vector<char> v;
for (int i = 0; i < s.length(); i++) {
if (s[i] != '#') {
v.push_back(s[i]);
} else {
if (!v.empty()) {
v.pop_back();
}
}
}
return string(v.begin(), v.end());
}
bool backspaceCompare(string s, string t) {
return cleanString(s) == cleanString(t);
}
int main() {
cout << backspaceCompare("ab#c", "ad#c") << endl;
cout << backspaceCompare("ab##", "c#d#") << endl;
cout << backspaceCompare("a#c", "b") << endl;
}
```

```
Output:
1
1
0
```

Runtime:

`O(n)`

, where`n = max(s.length, t.length)`

.Extra space:

`O(n)`

.

`vector`

instead of `stack`

?You can use the methods `push`

and `pop`

of the data structure `stack`

to build and clean the strings.

But `vector`

also has such methods: `push_back`

and `pop_back`

.

On the other hand, using `vector`

it is easier to construct a `string`

by constructor than using `stack`

after cleaning.

`O(n)`

time and `O(1)`

space?Yes, you can.

The simplest way is just to perform the erasure directly on strings `s`

and `t`

. But the run time complexity of `string::erase`

is not constant.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given an array of integers `nums`

and an integer `k`

, return the total number of continuous subarrays whose sum equals to `k`

.

```
Input: nums = [1,1,1], k = 2
Output: 2
```

```
Input: nums = [1,2,3], k = 3
Output: 2
```

`1 <= nums.length <= 2 * 10^4`

.`-1000 <= nums[i] <= 1000`

.`-10^7 <= k <= 10^7`

.

For each element, for all subarrays starting from it, choose the satisfied ones.

For `nums = [1, -1, 0]`

and `k = 0`

, you get `3`

subarrays for the result:

Three subarrays start from

`1`

, which are`[1]`

,`[1, -1]`

, and`[1, -1, 0]`

. Only the last two are satisfied.Two subarrays start from

`-1`

, which are`[-1]`

and`[-1, 0]`

. None is satisfied.Only

`[0]`

is the subarray starting from`0`

. It is satisfied.

```
#include <iostream>
#include <vector>
using namespace std;
int subarraySum(vector<int>& nums, int k) {
int count = 0;
for (int i = 0; i < nums.size(); i++) {
int sum = 0;
for (int j = i; j < nums.size(); j++) {
sum += nums[j];
if (sum == k) {
count++;
}
}
}
return count;
}
int main() {
vector<int> nums{1,1,1};
cout << subarraySum(nums, 2) << endl;
nums = {1,2,3};
cout << subarraySum(nums, 3) << endl;
nums = {1,-1,0};
cout << subarraySum(nums, 0) << endl;
}
```

```
Output:
2
2
3
```

Runtime:

`O(N^2)`

, where`N = nums.length`

.Extra space:

`O(1)`

.

In the solution above, many sums can be deducted from the previous ones.

For `nums = [1, 2, 3, 4]`

. Assume the sum of the subarrays `[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]`

were computed in the first loop. Then the sum of any other subarray can be deducted from those values.

`sum([2, 3]) = sum([1, 2, 3]) - sum([1])`

.`sum([2, 3, 4]) = sum([1, 2, 3, 4]) - sum([1])`

.`sum([3, 4]) = sum(1, 2, 3, 4) - sum(1, 2)`

.

In general, assume you have computed the sum `sum[i]`

for the subarray `[nums[0], nums[1], ..., nums[i]]`

for all `0 <= i < nums.length`

. Then the sum of the subarray `[nums[j], nums[j+1], ..., nums[i]]`

for any `0 <=j <= i`

can be computed as `sum[i] - sum[j]`

.

```
#include <iostream>
#include <vector>
using namespace std;
int subarraySum(vector<int>& nums, int k) {
vector<int> sum(nums.size());
sum[0] = nums[0];
for (int i = 1; i < nums.size(); i++) {
sum[i] = sum[i-1] + nums[i];
}
int count = 0;
for (int i = 0; i < nums.size(); i++) {
if (sum[i] == k) {
count++;
}
for (int j = 0; j < i; j++) {
if (sum[i] - sum[j] == k) {
count++;
}
}
}
return count;
}
int main() {
vector<int> nums{1,1,1};
cout << subarraySum(nums, 2) << endl;
nums = {1,2,3};
cout << subarraySum(nums, 3) << endl;
nums = {1,-1,0};
cout << subarraySum(nums, 0) << endl;
}
```

```
Output:
2
2
3
```

Runtime:

`O(N^2)`

, where`N = nums.length`

.Extra space:

`O(N)`

.

You can rewrite the condition `sum[i] - sum[j] == k`

in the inner loop of Solution 2 to `sum[i] - k == sum[j]`

.

Then that loop can rephrase to *"checking if* `sum[i] - k`

was already a value of **some** computed `sum[j]`

".

Now you can use an `unordered_map`

to store the `sums`

as indices for the fast lookup.

```
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
int subarraySum(vector<int>& nums, int k) {
int count = 0;
unordered_map<int, int> sums;
int sumi = 0;
for (int i = 0; i < nums.size(); i++) {
sumi += nums[i];
if (sumi == k) {
count++;
}
auto it = sums.find(sumi - k);
if (it != sums.end()) {
count += it->second;
}
sums[sumi]++;
}
return count;
}
int main() {
vector<int> nums{1,1,1};
cout << subarraySum(nums, 2) << endl;
nums = {1,2,3};
cout << subarraySum(nums, 3) << endl;
nums = {1,-1,0};
cout << subarraySum(nums, 0) << endl;
}
```

```
Output:
2
2
3
```

Runtime:

`O(N)`

, where`N = nums.length`

.Extra space:

`O(N)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

You are given an array of integers `stones`

where `stones[i]`

is the weight of the `i-th`

stone.

We are playing a game with the stones. On each turn, we choose the heaviest two stones and smash them together. Suppose the heaviest two stones have weights `x`

and `y`

with `x <= y`

. The result of this smash is:

If

`x == y`

, both stones are destroyed, andIf

`x != y`

, the stone of weight`x`

is destroyed, and the stone of weight`y`

has new weight`y - x`

.

At the end of the game, there is at most one stone left.

Return the smallest possible weight of the left stone. If there are no stones left, return `0`

.

```
Input: stones = [2,7,4,1,8,1]
Output: 1
Explanation:
We combine 7 and 8 to get 1, so the array converts to [2,4,1,1,1] then,
we combine 2 and 4 to get 2, so the array converts to [2,1,1,1] then,
we combine 2 and 1 to get 1, so the array converts to [1,1,1] then,
we combine 1 and 1 to get 0, so the array converts to [1] then that's the value of the last stone.
```

```
Input: stones = [1]
Output: 1
```

`1 <= stones.length <= 30`

.`1 <= stones[i] <= 1000`

.

The only things you want at any time are the two heaviest stones. One way of keeping this condition is by using `std::priority_queue`

.

```
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
int lastStoneWeight(vector<int>& stones) {
priority_queue<int> q(stones.begin(), stones.end());
while (q.size() >= 2) {
int y = q.top();
q.pop();
int x = q.top();
q.pop();
if (y != x) {
q.push(y - x);
}
}
return q.empty() ? 0 : q.top();
}
int main() {
vector<int> stones{2,7,4,1,8,1};
cout << lastStoneWeight(stones) << endl;
stones = {1};
cout << lastStoneWeight(stones) << endl;
}
```

```
Output:
1
1
```

Runtime: worst case

`O(NlogN)`

, on average`O(N)`

, where`N = stones.length`

.Extra space:

`O(N)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

You are keeping score for a baseball game with strange rules. The game consists of several rounds, where the scores of past rounds may affect future rounds' scores.

At the beginning of the game, you start with an empty record. You are given a list of strings `ops`

, where `ops[i]`

is the `i-th`

operation you must apply to the record and is one of the following:

An integer

`x`

- Record a new score of`x`

.`"+"`

- Record a new score that is the sum of the previous two scores. It is guaranteed there will always be two previous scores.`"D"`

- Record a new score that is double the previous score. It is guaranteed there will always be a previous score.`"C"`

- Invalidate the previous score, removing it from the record. It is guaranteed there will always be a previous score. Return the sum of all the scores on the record.

```
Input: ops = ["5","2","C","D","+"]
Output: 30
Explanation:
"5" - Add 5 to the record; the record is now [5].
"2" - Add 2 to the record; the record is now [5, 2].
"C" - Invalidate and remove the previous score; the record is now [5].
"D" - Add 2 * 5 = 10 to the record; the record is now [5, 10].
"+" - Add 5 + 10 = 15 to the record, record is now [5, 10, 15].
The total sum is 5 + 10 + 15 = 30.
```

```
Input: ops = ["5","-2","4","C","D","9","+","+"]
Output: 27
Explanation:
"5" - Add 5 to the record; the record is now [5].
"-2" - Add -2 to the record; the record is now [5, -2].
"4" - Add 4 to the record; the record is now [5, -2, 4].
"C" - Invalidate and remove the previous score; the record is now [5, -2].
"D" - Add 2 * -2 = -4 to the record; the record is now [5, -2, -4].
"9" - Add 9 to the record; the record is now [5, -2, -4, 9].
"+" - Add -4 + 9 = 5 to the record, record is now [5, -2, -4, 9, 5].
"+" - Add 9 + 5 = 14 to the record, record is now [5, -2, -4, 9, 5, 14].
The total sum is 5 + -2 + -4 + 9 + 5 + 14 = 27.
```

```
Input: ops = ["1"]
Output: 1
```

`1 <= ops.length <= 1000`

.`ops[i]`

is`"C"`

,`"D"`

,`"+"`

, or a string representing an integer in the range`[-3 * 10^4, 3 * 10^4]`

.For operation

`"+"`

, there will always be at least two previous scores on the record.For operations

`"C"`

and`"D"`

, there will always be at least one previous score on the record.

```
#include <vector>
#include <iostream>
#include <string>
#include <numeric>
using namespace std;
int calPoints(vector<string>& ops) {
vector<int> stk;
for (string& s : ops) {
if (s == "C") {
stk.pop_back();
} else if (s == "D") {
stk.push_back(stk.back()*2);
} else if (s == "+") {
stk.push_back(stk[stk.size() - 1] + stk[stk.size() - 2]);
} else {
stk.push_back(stoi(s));
}
}
return accumulate(stk.begin(), stk.end(), 0);
}
int main() {
vector<string> ops{"5","2","C","D","+"};
cout << calPoints(ops) << endl;
ops = {"5","-2","4","C","D","9","+","+"};
cout << calPoints(ops) << endl;
}
```

```
Output:
30
27
```

Runtime:

`O(N)`

, where`N = ops.length`

.Extra space:

`O(N)`

.

The data structure

`stk`

you might need to solve this problem is a stack. But here are the reasons you had better use`std::vector`

:`std::vector`

has also methods`push_back(value)`

and`pop_back()`

like the ones in stack.On the other hand, a stack does not give easy access to the second last element for the operator

`"+"`

in this problem.

`accumulate(stk.begin(), stk.end(), 0)`

computes the sum of the vector`stk`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Design a class to find the `k-th`

largest element in a stream. Note that it is the `k-th`

largest element in the sorted order, not the `k-th`

distinct element.

Implement `KthLargest`

class:

`KthLargest(int k, int[] nums)`

Initializes the object with the integer`k`

and the stream of integers`nums`

.`int add(int val)`

Appends the integer`val`

to the stream and returns the element representing the`k-th`

largest element in the stream.

```
Input
["KthLargest", "add", "add", "add", "add", "add"]
[[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
Output
[null, 4, 5, 5, 8, 8]
Explanation
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3); // return 4
kthLargest.add(5); // return 5
kthLargest.add(10); // return 5
kthLargest.add(9); // return 8
kthLargest.add(4); // return 8
```

`1 <= k <= 10^4`

.`0 <= nums.length <= 10^4`

.`-10^4 <= nums[i] <= 10^4`

.`-10^4 <= val <= 10^4`

.At most

`10^4`

calls will be made to add.It is guaranteed that there will be at least

`k`

elements in the array when you search for the`k-th`

element.

Sort the stream when initialization. And keep it sorted whenever you append a new value.

For `nums = [4, 5, 8, 2]`

and `k = 3`

.

Sort

`nums = [8, 5, 4, 2]`

.Adding

`3`

to`nums`

. It becomes`[8, 5, 4, 3, 2]`

. The third largest element is`4`

.Adding

`5`

to`nums`

. It becomes`[8, 5, 5, 4, 3, 2]`

. The third largest element is`5`

.Adding

`10`

to`nums`

. It becomes`[10, 8, 5, 5, 4, 3, 2]`

. The third largest element is`5`

.So on and so on.

```
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
class KthLargest {
vector<int> _nums;
int _k;
public:
KthLargest(int k, vector<int>& nums) : _nums(nums), _k(k) {
sort(_nums.begin(), _nums.end(), std::greater());
}
int add(int val) {
auto it = _nums.begin();
while (it != _nums.end() && val < *it) {
it++;
}
_nums.insert(it, val);
return *(_nums.begin() + _k - 1);
}
};
int main() {
vector<int> nums{4,5,8,2};
KthLargest a(3, nums);
cout << a.add(3) << endl;
cout << a.add(5) << endl;
cout << a.add(10) << endl;
cout << a.add(9) << endl;
cout << a.add(4) << endl;
}
```

```
Output:
4
5
5
8
8
```

Runtime:

`O(NlogN)`

, where`N = nums.length`

.Extra space:

`O(1)`

.

There is a data structure that has the property you want in this problem.

It is `std::priority_queue`

, which keeps its top element is always the largest one according to the comparison you define for the queue.

By default, the "less than" comparison is used for `std::priority_queue`

and the top one is always the biggest element.

If you want the top one is always the smallest element, you can use the comparison "greater than" for your queue.

```
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
class KthLargest {
priority_queue<int, vector<int>, greater<int>> _q;
int _k;
public:
KthLargest(int k, vector<int>& nums) :
_q(nums.begin(), nums.end()), _k(k) {
}
int add(int val) {
_q.push(val);
while (_q.size() > _k) {
_q.pop();
}
return _q.top();
}
};
int main() {
vector<int> nums{4,5,8,2};
KthLargest a(3, nums);
cout << a.add(3) << endl;
cout << a.add(5) << endl;
cout << a.add(10) << endl;
cout << a.add(9) << endl;
cout << a.add(4) << endl;
}
```

```
Output:
4
5
5
8
8
```

Runtime:

`O(N)`

, where`N = nums.length`

.Extra space:

`O(1)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given the `head`

of a linked list and an integer `val`

, remove all the nodes of the linked list that has `Node.val == val`

, and return *the new head*.

```
Input: head = [1,2,6,3,4,5,6], val = 6
Output: [1,2,3,4,5]
```

```
Input: head = [], val = 1
Output: []
```

```
Input: head = [7,7,7,7], val = 7
Output: []
```

The number of nodes in the list is in the range

`[0, 10^4]`

.`1 <= Node.val <= 50`

.`0 <= val <= 50`

.

```
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
```

Removing a node `A`

in a linked list means instead of connecting the previous node `A.pre`

to `A`

, you connect `A.pre`

to `A.next`

.

```
#include <iostream>
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
ListNode* removeElements(ListNode* head, int val) {
while (head && head->val == val) {
head = head->next;
}
if (head == nullptr) return nullptr;
ListNode* pre = head;
while (pre->next) {
if (pre->next->val == val) {
pre->next = pre->next->next;
} else {
pre = pre->next;
}
}
return head;
}
void print(ListNode* head) {
ListNode* node = head;
std::cout << "[";
while (node) {
std::cout << node->val << ",";
node = node->next;
}
std::cout << "]\n";
}
int main() {
ListNode sixb(6);
ListNode five(5, &sixb);
ListNode four(4, &five);
ListNode three(3, &four);
ListNode sixa(6, &three);
ListNode two(2, &sixa);
ListNode head(1, &two);
ListNode* newHead = removeElements(&head, 6);
print(newHead);
newHead = removeElements(nullptr, 1);
print(newHead);
ListNode seven4(7);
ListNode seven3(7, &seven4);
ListNode seven2(7, &seven3);
ListNode seven1(7, &seven2);
newHead = removeElements(&seven1, 7);
print(newHead);
}
```

```
Output:
[1,2,3,4,5,]
[]
[]
```

Runtime:

`O(N)`

, where`N`

is the number of nodes.Memory:

`O(1)`

.

`head`

has no `pre`

. You can create a dummy node for `head.pre`

.

```
#include <iostream>
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
ListNode* removeElements(ListNode* head, int val) {
ListNode preHead(2023, head);
ListNode* pre = &preHead;
while (pre->next) {
if (pre->next->val == val) {
pre->next = pre->next->next;
} else {
pre = pre->next;
}
}
return preHead.next;
}
void print(ListNode* head) {
ListNode* node = head;
std::cout << "[";
while (node) {
std::cout << node->val << ",";
node = node->next;
}
std::cout << "]\n";
}
int main() {
ListNode sixb(6);
ListNode five(5, &sixb);
ListNode four(4, &five);
ListNode three(3, &four);
ListNode sixa(6, &three);
ListNode two(2, &sixa);
ListNode head(1, &two);
ListNode* newHead = removeElements(&head, 6);
print(newHead);
newHead = removeElements(nullptr, 1);
print(newHead);
ListNode seven4(7);
ListNode seven3(7, &seven4);
ListNode seven2(7, &seven3);
ListNode seven1(7, &seven2);
newHead = removeElements(&seven1, 7);
print(newHead);
}
```

```
Output:
[1,2,3,4,5,]
[]
[]
```

Runtime:

`O(N)`

, where`N`

is the number of nodes.Memory:

`O(1)`

.

Depending on your real situation, in practice, you might need to deallocate memory for the removed nodes; especially when they were allocated by the `new`

operator.

```
ListNode* removeElements(ListNode* head, int val) {
ListNode preHead(2022, head);
ListNode* pre = &preHead;
while (pre->next) {
if (pre->next->val == val) {
ListNode* node = pre->next;
pre->next = node->next;
delete node;
} else {
pre = pre->next;
}
}
return preHead.next;
}
```

In some linked list problems where

`head`

needs to be treated as a special case, you can create a previous dummy node for it to adapt the general algorithm.Be careful with memory leak when removing nodes of the linked list containing pointers.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Every valid email consists of a local name and a domain name, separated by the `'@'`

sign. Besides lowercase letters, the email may contain one or more `'.'`

or `'+'`

.

For example, in `"alice@leetcode.com"`

, `"alice"`

is the local name, and `"leetcode.com"`

is the domain name.

If you add periods `'.'`

between some characters in the local name part of an email address, mail sent there will be forwarded to the same address without dots in the local name. Note that this rule does not apply to domain names.

For example, `"alice.z@leetcode.com"`

and `"alicez@leetcode.com"`

forward to the same email address.

If you add a plus `'+'`

in the local name, everything after the first plus sign will be ignored. This allows certain emails to be filtered. Note that this rule does not apply to domain names.

For example, `"m.y+name@email.com"`

will be forwarded to `"my@email.com"`

.

It is possible to use both of these rules at the same time.

Given an array of strings `emails`

where we send one email to each `emails[i]`

, return the number of different addresses that actually receive mails.

```
Input: emails = ["test.email+alex@leetcode.com","test.e.mail+bob.cathy@leetcode.com","testemail+david@lee.tcode.com"]
Output: 2
Explanation: "testemail@leetcode.com" and "testemail@lee.tcode.com" actually receive mails.
```

```
Input: emails = ["a@leetcode.com","b@leetcode.com","c@leetcode.com"]
Output: 3
```

`1 <= emails.length <= 100`

.`1 <= emails[i].length <= 100`

.`emails[i]`

consist of lowercase English letters,`'+'`

,`'.'`

and`'@'`

.Each

`emails[i]`

contains exactly one`'@'`

character.All local and domain names are non-empty.

Local names do not start with a

`'+'`

character.Domain names end with the

`".com"`

suffix.

Do exactly the steps the problem describes:

Extract the local name.

Ignore all characters after

`'+'`

in it.Ignore all

`'.'`

in it.Combine the local name with the domain one to form the clean email address.

```
#include<string>
#include<iostream>
#include<vector>
#include <unordered_set>
using namespace std;
int numUniqueEmails(vector<string>& emails) {
unordered_set<string> s;
for (auto e: emails) {
auto apos = e.find('@');
string local = e.substr(0, apos); // extract the local name
local = local.substr(0, local.find('+')); // ignore all characters after '+'
for (auto it = local.find('.'); it != string::npos; it = local.find('.')) {
local.erase(it, 1); // remove each '.' found in local
}
s.insert(local + e.substr(apos)); // combine local name with domain one
}
return s.size();
}
int main() {
vector<string> emails = {"test.email+alex@leetcode.com",
"test.e.mail+bob.cathy@leetcode.com",
"testemail+david@lee.tcode.com"};
cout << numUniqueEmails(emails) << endl;
emails = {"a@leetcode.com","b@leetcode.com","c@leetcode.com"};
cout << numUniqueEmails(emails) << endl;
emails = {"test.email+alex@leetcode.com","test.email.leet+alex@code.com"};
cout << numUniqueEmails(emails) << endl;
}
```

```
Output:
2
3
2
```

Runtime:

`O(N*M^2)`

, where`N = emails.length`

,`M = max(emails[i].length)`

. Explanation: you loop over`N`

emails. Then you might loop over the length of each email,`O(M)`

, to remove the character`'.'`

. The removal might cost`O(M)`

.Extra space:

`O(N*M)`

(the set of emails).

The runtime of removing characters in `std::string`

is not constant. To avoid that complexity you can build up the clean email addresses from scratch.

```
#include<string>
#include<iostream>
#include<vector>
#include <unordered_set>
using namespace std;
int numUniqueEmails(vector<string>& emails) {
unordered_set<string> s;
for (auto e: emails) {
string address;
int i = 0;
while (e[i] != '@' && e[i] != '+') { // the local name ends here
if (e[i++] == '.') { // ignore each '.' found
continue;
}
address += e[i++]; // add valid characters to local name
}
address += e.substr(e.find('@', i)); // combine local name with domain one
s.insert(address);
}
return s.size();
}
int main() {
vector<string> emails = {"test.email+alex@leetcode.com",
"test.e.mail+bob.cathy@leetcode.com",
"testemail+david@lee.tcode.com"};
cout << numUniqueEmails(emails) << endl;
emails = {"a@leetcode.com","b@leetcode.com","c@leetcode.com"};
cout << numUniqueEmails(emails) << endl;
emails = {"test.email+alex@leetcode.com","test.email.leet+alex@code.com"};
cout << numUniqueEmails(emails) << endl;
}
```

```
Output:
2
3
2
```

Runtime:

`O(N*M)`

, where`N = emails.length`

,`M = max(emails[i].length)`

.Extra space:

`O(N*M)`

.

- A
`string`

can be concatenated with a`char`

and another`string`

by`+`

operator.

```
std::string address = "name";
address += '@'; // "name@"
address += "domain.com"; // "name@domain.com"
```

- string::substr(pos = 0, count = npos) returns the substring of length
`count`

starting from the position`pos`

of the string`string`

.

```
std::string address = "name@domain.com";
cout << address.substr(address.find('.')); // ".com"
cout << address.substr(0, address.find('@')); // "name"
```

- string::find(char, pos=0) returns the position of the first
`char`

which appears in the string`string`

starting from`pos`

.

Do not use

`std::set`

or`std::map`

unless you want the keys to be*in order*(*sorted*). Use*unordered containers*like std::unordered_set or std::unordered_map instead. They use hashed keys for faster lookup.Do not blindly/lazily use

`string.find(something)`

. If you know where to start the search, use`string.find(something, pos)`

with a**specific**`pos`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given a 2D `grid`

of size `m x n`

and an integer `k`

. You need to shift the grid `k`

times.

In one shift operation:

Element at

`grid[i][j]`

moves to`grid[i][j + 1]`

.Element at

`grid[i][n - 1]`

moves to`grid[i + 1][0]`

.Element at

`grid[m - 1][n - 1]`

moves to`grid[0][0]`

.

Return the 2D grid after applying shift operation `k`

times.

```
Input: grid = [[1,2,3],[4,5,6],[7,8,9]], k = 1
Output: [[9,1,2],[3,4,5],[6,7,8]]
```

```
Input: grid = [[3,8,1,9],[19,7,2,5],[4,6,11,10],[12,0,21,13]], k = 4
Output: [[12,0,21,13],[3,8,1,9],[19,7,2,5],[4,6,11,10]]
```

```
Input: grid = [[1,2,3],[4,5,6],[7,8,9]], k = 9
Output: [[1,2,3],[4,5,6],[7,8,9]]
```

`m == grid.length`

.`n == grid[i].length`

.`1 <= m <= 50`

.`1 <= n <= 50`

.`-1000 <= grid[i][j] <= 1000`

.`0 <= k <= 100`

.

You can convert the 2D `grid`

into a 1D vector `v`

to perform the shifting easier. One way of doing this is concatenating the rows of the matrix.

If you shift the grid

`k = i*N`

times where`N = v.size()`

and`i`

is any non-negative integer, you go back to the original grid; i.e. you did not shift it.If you shift the grid

`k`

times with`0 < k < N`

, the first element of the result starts from`v[N - k]`

.In general, the first element of the result starts from

`v[N - k%N]`

.

For `grid = [[1,2,3],[4,5,6],[7,8,9]]`

:

It can be converted into a 1D vector

`v = [1,2,3,4,5,6,7,8,9]`

of size`m*n = 9`

.With

`k = 1`

the shifted`grid`

now starts from`v[9 - 1] = 9`

.The final result is

`grid = [[9,1,2][3,4,5][6,7,8]]`

.

```
#include <vector>
#include <iostream>
using namespace std;
vector<vector<int>> shiftGrid(vector<vector<int>>& grid, int k) {
vector<int> v;
for (auto& r : grid) {
v.insert(v.end(), r.begin(), r.end());
}
const int m = grid.size();
const int n = grid[0].size();
int p = v.size() - (k % v.size());
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (p == v.size()) {
p = 0;
}
grid[i][j] = v[p++];
}
}
return grid;
}
void printResult(vector<vector<int>>& grid) {
cout << "[";
for (auto& r : grid) {
cout << "[";
for (int a: r) {
cout << a << ",";
}
cout << "]";
}
cout << "]\n";
}
int main() {
vector<vector<int>> grid{{1,2,3},{4,5,6},{7,8,9}};
auto result = shiftGrid(grid, 1);
printResult(result);
grid = {{3,8,1,9},{19,7,2,5},{4,6,11,10},{12,0,21,13}};
result = shiftGrid(grid, 4);
printResult(result);
grid = {{1,2,3},{4,5,6},{7,8,9}};
result = shiftGrid(grid, 9);
printResult(result);
}
```

```
Output:
[[9,1,2,][3,4,5,][6,7,8,]]
[[12,0,21,13,][3,8,1,9,][19,7,2,5,][4,6,11,10,]]
[[1,2,3,][4,5,6,][7,8,9,]]
```

Runtime:

`O(mn)`

(the nested`for`

loops), where`m = grid.length`

,`n = grid[i].length`

.Extra space:

`O(mn)`

(the vector`v`

).

To convert a 2D matrix into a 1D vector, you can use the vector's function

`insert()`

.The modulo operator

`%`

is usually used to index an array to ensure the index is inbound.

*Thanks for reading. Feel free to share your thought about my content.*

*What is your approach? The problem was picked from* *leetcode.com**. You can submit your solution in any programming language and check the performance.*

You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once.

*Return the single element that appears only once.*

Your solution must run in `O(log n)`

time and `O(1)`

space.

```
Input: nums = [1,1,2,3,3,4,4,8,8]
Output: 2
```

```
Input: nums = [3,3,7,7,10,11,11]
Output: 10
```

`1 <= nums.length <= 10^5`

.`0 <= nums[i] <= 10^5`

.

```
#include <vector>
#include <iostream>
using namespace std;
int singleNonDuplicate(vector<int>& nums) {
for (int i = 0; i < nums.size() - 1; i += 2) {
if (nums[i] != nums[i + 1]) {
return nums[i];
}
}
return nums[0];
}
int main() {
vector<int> nums{1,1,2,3,3,4,4,8,8};
cout << singleNonDuplicate(nums) << endl;
nums = {3,3,7,7,10,11,11};
cout << singleNonDuplicate(nums) << endl;
nums = {3};
cout << singleNonDuplicate(nums) << endl;
}
```

```
Output:
2
10
3
```

Runtime

`O(n/2)`

, where`n = nums.length`

.Memory

`O(1)`

.

Since `nums`

is sorted, you can perform a binary search on it.

Let us divide `nums`

into two halves.

If the single element belongs to the right half, all elements of the left half satisfy `nums[2*i] == nums[2*i + 1]`

.

Conversely, if the single element belongs to the left half, that condition is violated at the middle element of `nums`

(the middle one with an even index).

For `nums = [1,1,2,3,3,4,4,8,8]`

:

The middle element with even index is

`nums[4] = 3`

. It is not equal to`nums[4 + 1] = 4`

. So the single element must be somewhere in the left half`[1,1,2,3,3]`

.The middle element of

`nums = [1,1,2,3,3]`

with even index is`nums[2] = 2`

, which is not equal to`nums[2 + 1] = 3`

. So the single element must be somewhere in the left half`[1,1,2]`

.The middle element of

`nums = [1,1,2]`

with even index is`nums[0] = 1 == nums[0 + 1]`

. So the single element must be somewhere in the right half`[2]`

.`nums = [2]`

contains only one element. So`2`

is the result.

```
#include <vector>
#include <iostream>
using namespace std;
int singleNonDuplicate(vector<int>& nums) {
int left = 0;
int right = nums.size() - 1;
while (left < right) {
int mid = (right + left)/4 * 2; // to make sure mid is even
if (nums[mid] != nums[mid + 1]) {
right = mid;
} else {
left = mid + 2;
}
}
return nums[right];
}
int main() {
vector<int> nums{1,1,2,3,3,4,4,8,8};
cout << singleNonDuplicate(nums) << endl;
nums = {3,3,7,7,10,11,11};
cout << singleNonDuplicate(nums) << endl;
nums = {3};
cout << singleNonDuplicate(nums) << endl;
}
```

```
Output:
2
10
3
```

Runtime

`O(logn)`

, where`n = nums.length`

.Memory

`O(1)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given an integer array `nums`

, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order.

Return the shortest such subarray and output its length.

```
Input: nums = [2,6,4,8,10,9,15]
Output: 5
Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order.
```

```
Input: nums = [1,2,3,4]
Output: 0
```

```
Input: nums = [1]
Output: 0
```

`1 <= nums.length <= 10^4`

.`-10^5 <= nums[i] <= 10^5`

.

**Follow up**: Can you solve it in `O(n)`

time complexity?

Comparing `nums = [2,6,4,8,10,9,15]`

with its sorted one `sortedNums = [2,4,6,8,9,10,15]`

:

The first position that makes the difference is

`left = 1`

, where`6 != 4`

.The last position that makes the difference is

`right = 5`

, where`9 != 10`

.The length of that shortest subarray is

`right - left + 1 = 5`

.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int findUnsortedSubarray(vector<int>& nums) {
vector<int> sortedNums = nums;
sort(sortedNums.begin(), sortedNums.end());
int left = 0;
while (left < nums.size() && nums[left] == sortedNums[left]) {
left++;
}
int right = nums.size() - 1;
while (right >= 0 && nums[right] == sortedNums[right]) {
right--;
}
return left >= right ? 0 : right - left + 1;
}
int main() {
vector<int> nums{2,6,4,8,10,9,15};
cout << findUnsortedSubarray(nums) << endl;
nums = {1,2,3,4};
cout << findUnsortedSubarray(nums) << endl;
nums = {1};
cout << findUnsortedSubarray(nums) << endl;
}
```

```
Output:
5
0
0
```

Runtime:

`O(nlogn)`

, where`n = nums.length`

because of the sorting algorithm.Extra space:

`O(n)`

.

Assume the subarray `A = [nums[0], ..., nums[i - 1]]`

is sorted. What would be the wanted `right`

position for the subarray `B = [nums[0], ..., nums[i - 1], nums[i]]`

?

If `nums[i]`

is smaller than `max(A)`

, the longer subarray `B`

is not in ascending order. You might need to sort it, which means `right = i`

.

Similarly, assume the subarray `C = [nums[j + 1], ..., nums[n - 1]]`

is sorted. What would be the wanted `left`

position for the subarray `D = [nums[j], nums[j + 1], ..., nums[n - 1]]`

?

If `nums[j]`

is bigger than `min(C)`

, the longer subarray `D`

is not in ascending order. You might need to sort it, which means `left = j`

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int findUnsortedSubarray(vector<int>& nums) {
const int n = nums.size();
int left = n - 1;
int min = nums[n - 1];
for (int i = n - 1; i >= 0; i--) {
if (min < nums[i]) {
left = i;
} else {
min = nums[i];
}
}
int right = 0;
int max = nums[0];
for (int i = 0; i < nums.size(); i++) {
if (max > nums[i]) {
right = i;
} else {
max = nums[i];
}
}
return left >= right ? 0 : right - left + 1;
}
int main() {
vector<int> nums{2,6,4,8,10,9,15};
cout << findUnsortedSubarray(nums) << endl;
nums = {1,2,3,4};
cout << findUnsortedSubarray(nums) << endl;
nums = {1};
cout << findUnsortedSubarray(nums) << endl;
}
```

```
Output:
5
0
0
```

Runtime:

`O(n)`

, where`n = nums.length`

.Extra space:

`O(1)`

.

Solution 2 helped you identify the shortest subarray (by the `left`

and `right`

indices) needed to be sorted in order to sort the whole array.

That means in some cases you can sort an array with complexity `O(N + mlogm) < O(NlogN)`

where `N`

is the length of the whole array and `m`

is the length of the shortest subarray.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book "10 Classic Coding Challenges"**.*

You are given a string `s`

and an integer `k`

, a `k`

duplicate removal consists of choosing `k`

adjacent and the same letters from `s`

and removing them, causing the left and the right side of the deleted substring to concatenate together.

We repeatedly make `k`

duplicate removals on `s`

until we no longer can.

Return the final string after all such duplicate removals have been made. It is guaranteed that the answer is unique.

```
Input: s = "abcd", k = 2
Output: "abcd"
Explanation: There is nothing to delete.
```

```
Input: s = "deeedbbcccbdaa", k = 3
Output: "aa"
Explanation:
First delete "eee" and "ccc", get "ddbbbdaa"
Then delete "bbb", get "dddaa"
Finally delete "ddd", get "aa"
```

```
Input: s = "pbbcggttciiippooaais", k = 2
Output: "ps"
```

`1 <= s.length <= 10^5`

.`2 <= k <= 10^4`

.`s`

only contains lower case English letters.

Construct a stack of strings that has adjacent equal letters and perform the removal during building those strings.

For `s = "deeedbbcccbdaa"`

and `k = 3`

:

The first built string is

`"d"`

.Then

`"eee"`

with exact length`k`

, remove this string.The next character is

`'d'`

, which equals the last character of the last string`"d"`

, merge them together. The first string becomes`"dd"`

.The next string is

`"bb"`

.Then

`"ccc"`

is removed.The next character

`'b'`

is merged with the last string (`"bb"`

) to become`"bbb"`

and be removed.The next character

`'d'`

is merged with the last string (`"dd"`

) to become`"ddd"`

and be removed.The remaining string is

`"aa"`

.

```
#include <iostream>
#include <vector>
using namespace std;
string removeDuplicates(string s, int k) {
vector<string> stk;
int i = 0;
while (i < s.length()) {
string a; // to store adjacent equal letters
// perform the merge
if (!stk.empty() && s[i] == stk.back().back()) {
a = move(stk.back());
stk.pop_back();
}
int j = i;
while (j < s.length() && s[j] == s[i]) {
a += s[j];
// remove the k-duplicate
if (a.length() == k) {
a = "";
}
j++;
}
if (!a.empty()) {
stk.push_back(a);
}
i = j;
}
s = "";
for (auto& str : stk) {
s += str;
}
return s;
}
int main() {
cout << removeDuplicates("abcd", 2) << endl;
cout << removeDuplicates("deeedbbcccbdaa", 3) << endl;
cout << removeDuplicates("pbbcggttciiippooaais", 2) << endl;
}
```

```
abcd
aa
ps
```

Runtime:

`O(N)`

, where`N = s.length`

.Extra space:

`O(N)`

.

The data structure `stk`

you might need to solve this problem is a stack. But here are the reasons you had better use `std::vector`

:

`std::vector`

has also methods`push_back(value)`

and`pop_back()`

like the ones in stack.On the other hand, it is faster for a vector to perform the string concatenation at the end.

*Thanks for reading! Feel free to share your thought and get* *my FREE book "10 Classic Coding Challenges"**.*

Given a string containing digits from `2-9`

inclusive, return all possible letter combinations that the number could represent. Return the answer in any order.

A mapping of digits to letters (just like on the telephone buttons) is given below. Note that `1`

does not map to any letters.

```
Input: digits = "23"
Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]
```

```
Input: digits = ""
Output: []
```

```
Input: digits = "2"
Output: ["a","b","c"]
```

`0 <= digits.length <= 4`

.`digits[i]`

is a digit in the range`['2', '9']`

.

If you know the combinations `result`

of a string `digits`

, what is the result of extending it one more digit?

**Answer**: The new result is constructed by adding each letter of the mapping of the new digit to each string of the `result`

.

Assume you have computed the result of `digits = "2"`

, which is `["a","b","c"]`

.

To compute the result of `digits = "23"`

, you add each letter of the mapping `'3' -> {'d', 'e', 'f'}`

to each string `"a", "b", "c"`

.

You get the new result `["ad","ae","af","bd","be","bf","cd","ce","cf"]`

.

```
#include <vector>
#include <iostream>
#include <unordered_map>
using namespace std;
void combination(string& digits, unordered_map<char, vector<char> >& m,
int i, vector<string>& result) {
if (i >= digits.length()) {
return;
}
if (result.empty()) {
result = {""};
}
vector<string> newResult;
for (string& s : result) {
for (auto c : m[digits[i]]) {
newResult.push_back(s + c);
}
}
result.swap(newResult);
combination(digits, m, i + 1, result);
}
vector<string> letterCombinations(string digits) {
unordered_map<char, vector<char> > m{{'2', {'a', 'b', 'c'}},
{'3', {'d', 'e', 'f'}},
{'4', {'g', 'h', 'i'}},
{'5', {'j', 'k', 'l'}},
{'6', {'m', 'n', 'o'}},
{'7', {'p', 'q', 'r', 's'}},
{'8', {'t', 'u', 'v'}},
{'9', {'w', 'x', 'y', 'z'}}};
vector<string> result;
combination(digits, m, 0, result);
return result;
}
void printResult(vector<string>& result) {
cout << "[";
for (string& s : result) {
cout << s << ",";
}
cout << "]\n";
}
int main() {
vector<string> result = letterCombinations("23");
printResult(result);
result = letterCombinations("");
printResult(result);
result = letterCombinations("2");
printResult(result);
}
```

```
Output:
[ad,ae,af,bd,be,bf,cd,ce,cf,]
[]
[a,b,c,]
```

Runtime:

`O(3^N)`

, where`N = digits.length`

. In this problem,`N`

is very small (`N <= 4`

).Extra space:

`O(1)`

(the small map).

You can use the assignment operator `'='`

for `result.swap(newResult)`

, i.e. `result = newResult`

.

But this assignment allocates additional memory for a copy of `newResult`

before assigning it to `result`

.

The `std::swap()`

algorithm avoids such copying by using `std::move()`

. It exchanges the contents of each other without allocating additional memory.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

We define the usage of capitals in a word to be right when one of the following cases holds:

All letters in this word are capitals, like

`"USA"`

.All letters in this word are not capitals, like

`"leetcode"`

.Only the first letter in this word is capital, like

`"Google"`

.

Given a string `word`

, return `true`

if the usage of capitals in it is right.

```
Input: word = "USA"
Output: true
```

```
Input: word = "FlaG"
Output: false
```

`1 <= word.length <= 100`

,`word`

consists of lowercase and uppercase English letters.

Only when the first two characters of the `word`

are uppercase, the rest must be the same. Otherwise, the rest is always lowercase.

```
#include <string>
#include <iostream>
using namespace std;
bool isValidCase(const char& c, const bool isLower) {
if (isLower) {
return 'a' <= c && c <= 'z';
}
return 'A' <= c && c <= 'Z';
}
bool detectCapitalUse(string word) {
if (word.length() == 1) {
return true;
}
bool isLower = true;
if (isValidCase(word[0], false) && isValidCase(word[1], false)) {
isLower = false;
}
for (int i = 1; i < word.length(); i++) {
if (!isValidCase(word[i], isLower)) {
return false;
}
}
return true;
}
int main() {
cout << detectCapitalUse("USA") << endl;
cout << detectCapitalUse("FlaG") << endl;
cout << detectCapitalUse("leetcode") << endl;
cout << detectCapitalUse("Google") << endl;
}
```

```
Output:
1
0
1
1
```

Runtime:

`O(N)`

, where`N = word.length`

.Extra space:

`O(1)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given an integer `n`

, return `true`

if it is a power of three. Otherwise, return `false`

.

An integer `n`

is a power of three, if there exists an integer `x`

such that `n == 3^x`

.

```
Input: n = 27
Output: true
Explanation: 27 = 3^3.
```

```
Input: n = 0
Output: false
Explanation: There is no x where 3^x = 0.
```

```
Input: n = -1
Output: false
Explanation: There is no x where 3^x = (-1).
```

`-2^31 <= n <= 2^31 - 1`

.

**Follow up**: Could you solve it without loops/recursion?

```
#include <iostream>
using namespace std;
bool isPowerOfThree(int n) {
while (n % 3 == 0 && n > 0) {
n /= 3;
}
return n == 1;
}
int main() {
cout << isPowerOfThree(27) << endl;
cout << isPowerOfThree(0) << endl;
cout << isPowerOfThree(-1) << endl;
}
```

```
Output:
1
0
0
```

Runtime:

`O(logn)`

.Extra space:

`O(1)`

.

A power of three must divide another bigger one, i.e. `3^x | 3^y`

where `0 <= x <= y`

.

Because the constraint of the problem is `n <= 2^31 - 1`

, you can choose the biggest power of three in this range to test the others.

It is `3^19 = 1162261467`

. The next power will exceed `2^31 = 2147483648`

.

```
#include <iostream>
using namespace std;
bool isPowerOfThree(int n) {
return n > 0 && 1162261467 % n == 0;
}
int main() {
cout << isPowerOfThree(27) << endl;
cout << isPowerOfThree(0) << endl;
cout << isPowerOfThree(-1) << endl;
}
```

```
Output:
1
0
0
```

Runtime:

`O(1)`

.Extra space:

`O(1)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given a set of **distinct** positive integers `nums`

, return the largest subset `answer`

such that every pair `(answer[i], answer[j])`

of elements in this subset satisfies:

`answer[i] % answer[j] == 0`

, or`answer[j] % answer[i] == 0`

.

If there are multiple solutions, return any of them.

```
Input: nums = [1,2,3]
Output: [1,2]
Explanation: [1,3] is also accepted.
```

```
Input: nums = [1,2,4,8]
Output: [1,2,4,8]
```

`1 <= nums.length <= 1000`

.`1 <= nums[i] <= 2 * 10^9`

.All the integers in

`nums`

are**unique**.

Note that the condition `a % b == 0`

is called `a`

is divisible by `b`

. In mathematics, it can also be called `b`

divides `a`

and be written as `b | a`

.

The symmetry of the divisibility criteria means it does not count the ordering of the `answer`

. You could sort the vector `nums`

before trying to find the longest subset `answer = [answer[0], answer[1], ..., answer[m]]`

where `answer[i] | answer[j]`

with all `0 <= i <= j <= m`

.

Now assuming the `nums`

were sorted. For each `i`

, you need to find the largest subset `maxSubset[i]`

starting from `nums[i]`

. And the final answer is the largest one among them.

```
Input: nums = [2, 4, 3, 9, 8].
Sorted nums = [2, 3, 4, 8, 9].
maxSubset[0] = [2, 4, 8].
maxSubset[1] = [3, 9].
maxSubset[2] = [4, 8].
maxSubset[3] = [8].
maxSubset[4] = [9].
Output: [2, 4, 8].
```

Note that for a sorted `nums`

, if `nums[i] | nums[j]`

for some `i < j`

, then `maxSubset[j]`

is a subset of `maxSubset[i]`

.

For example, `maxSubset[2]`

is a subset of `maxSubset[0]`

in Example 3 because `nums[0] = 2 | 4 = nums[2]`

.

That might lead to some unnecessary recomputing. To avoid it, you could use *dynamic programming* to store the `maxSubset[j]`

you have already computed.

```
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
//! @brief compute the maxSubset[i] starting from nums[i]
//! and store it to _map[i]
//! @note nums is sorted
vector<int> largestDivisibleSubsetOf(vector<int>& nums, int i,
unordered_map<int, vector<int> >& _map) {
if (_map.find(i) != _map.end()) {
return _map[i];
}
vector<int> maxSubset{nums[i]};
if (i == nums.size() - 1) {
_map.insert({i, maxSubset});
return maxSubset;
}
for (int j = i + 1; j < nums.size(); j++) {
if (nums[j] % nums[i] == 0) {
auto subset = largestDivisibleSubsetOf(nums, j, _map);
subset.push_back(nums[i]);
if (maxSubset.size() < subset.size()) {
maxSubset = subset;
}
}
}
_map.insert({i, maxSubset});
return maxSubset;
}
vector<int> largestDivisibleSubset(vector<int>& nums) {
if (nums.size() <= 1) {
return nums;
}
unordered_map<int, vector<int> > _map;
sort(nums.begin(), nums.end());
vector<int> answer;
for (int i = 0; i < nums.size(); i++) {
auto maxSubset = largestDivisibleSubsetOf(nums, i, _map);
if (answer.size() < maxSubset.size()) {
answer = maxSubset;
}
}
return answer;
}
void printSolution(vector<int>& result) {
cout << "[";
for (auto& v : result) {
cout << v << ",";
}
cout << "]" << endl;
}
int main() {
vector<int> nums{2,1,3};
auto answer = largestDivisibleSubset(nums);
printSolution(answer);
nums = {1,2,4,8};
answer = largestDivisibleSubset(nums);
printSolution(answer);
}
```

```
Output:
[2,1,]
[8,4,2,1,]
```

Runtime:

`O(2^N)`

, where`N = nums.length`

.Extra space:

`O(N^2)`

.

`maxSubset`

In the brute-force solution above, you used a big `map`

to log all `maxSubset[i]`

though you need only the largest one at the end.

One way to save memory (and eventually improve performance) is just storing the representative of the chain relationship between the values `nums[i]`

of the `maxSubset`

through their indices mapping.

That means if `maxSubset[i] = [nums[i0] | nums[i1] | ... | nums[iN1]] | nums[iN]]`

, you could log `pre[iN] = iN1`

, ..., `prev[i1] = i0`

.

Then all you need to find is only the last index `iN`

of the largest `maxSubset`

.

```
Input: nums = [2, 4, 3, 9, 8].
sorted nums = [2, 3, 4, 8, 9].
pre[0] = -1 (there is no nums[i] | nums[0]).
pre[1] = -1 (there is no nums[i] | nums[1]).
pre[2] = 0 (nums[0] is the only divisor of nums[2]).
pre[3] = 2 (for the largest subset though nums[0] and nums[2] are both divisors of nums[3]).
pre[4] = 1 (nums[1] is the only divisor of nums[4]).
iN = 3 ([2 | 4 | 8] is the largest maxSubset).
Output: [8, 4, 2].
```

```
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> largestDivisibleSubset(vector<int>& nums) {
if (nums.size() <= 1) {
return nums;
}
sort(nums.begin(), nums.end());
int maxSize = 0; // the size of the resulting subset
int maxindex = 0; // nums[maxindex] is the largest value of the resulting subset
vector<int> subsetSize(nums.size(), 1); // subsetSize[i] stores the size of the
// largest subset having biggest number nums[i]
vector<int> pre(nums.size(), -1); // pre[i] stores the previous index of
// i in their largest subset
for (int i = 0; i < nums.size(); i++) {
// find the previous nums[j] that make subsetSize[i] largest
for (int j = i - 1; j >= 0; j--) {
if (nums[i] % nums[j] == 0 && subsetSize[j] + 1 > subsetSize[i]) {
subsetSize[i] = subsetSize[j] + 1;
pre[i] = j;
}
}
// update the largest subset
if (maxSize < subsetSize[i]) {
maxSize = subsetSize[i];
maxindex = i;
}
}
vector<int> result;
while (maxindex != -1) {
result.push_back(nums[maxindex]);
maxindex = pre[maxindex];
}
return result;
}
void printSolution(vector<int>& result) {
cout << "[";
for (auto& v : result) {
cout << v << ",";
}
cout << "]" << endl;
}
int main() {
vector<int> nums{2,1,3};
auto result = largestDivisibleSubset(nums);
printSolution(result);
nums = {1,2,4,8};
result = largestDivisibleSubset(nums);
printSolution(result);
}
```

```
Output:
[2,1,]
[8,4,2,1,]
```

Runtime:

`O(N^2)`

, where`N = nums.length`

.Extra space:

`O(N)`

.

In this interesting problem, we use index mapping to simplify everything. That improves the performance in both runtime and memory.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given a linked list, swap every two adjacent nodes and return its head. You must solve the problem without modifying the values in the list's nodes (i.e., only nodes themselves may be changed.)

```
Input: head = [1,2,3,4]
Output: [2,1,4,3]
```

```
Input: head = []
Output: []
```

```
Input: head = [1]
Output: [1]
```

The number of nodes in the list is in the range

`[0, 100]`

.`0 <= Node.val <= 100`

.

Draw a picture of the swapping to identify the correct order of the update.

Denote `(cur, next)`

the pair of nodes you want to swap and `prev`

be the previous node that links to `cur`

. Here are the steps you need to perform for the swapping.

Update the links between nodes.

Go to the next pair.

```
#include <iostream>
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
ListNode* swapPairs(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return head;
}
ListNode* preNode = nullptr;
ListNode* curNode = head;
ListNode* nextNode = head->next;
head = nextNode;
while (curNode != nullptr && nextNode != nullptr) {
curNode->next = nextNode->next;
nextNode->next = curNode;
if (preNode) {
preNode->next = nextNode;
}
preNode = curNode;
curNode = curNode->next;
if (curNode) {
nextNode = curNode->next;
}
}
return head;
}
void print(ListNode* head) {
ListNode* node = head;
std::cout << "[";
while (node != nullptr) {
std::cout << node->val << ",";
node = node->next;
}
std::cout << "]" << std::endl;
}
int main() {
ListNode four(4);
ListNode three(3, &four);
ListNode two(2, &three);
ListNode one(1, &two);
print(swapPairs(&one));
ListNode five(5);
print(swapPairs(nullptr));
print(swapPairs(&five));
}
```

```
Output:
[2,1,4,3,]
[]
[5,]
```

Runtime:

`O(N)`

, where`N`

is the number of nodes.Extra space:

`O(1)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

A **wiggle sequence** is a sequence where the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with one element and a sequence with two non-equal elements are trivially wiggle sequences.

For example,

`[1, 7, 4, 9, 2, 5]`

is a wiggle sequence because the differences`(6, -3, 5, -7, 3)`

alternate between positive and negative.In contrast,

`[1, 4, 7, 2, 5]`

and`[1, 7, 4, 5, 5]`

are not wiggle sequences. The first is not because its first two differences are positive, and the second is not because its last difference is zero.

A **subsequence** is obtained by deleting some elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.

Given an integer array `nums`

, return the length of the longest wiggle subsequence of `nums`

.

```
Input: nums = [1,7,4,9,2,5]
Output: 6
Explanation: The entire sequence is a wiggle sequence with differences (6, -3, 5, -7, 3).
```

```
Input: nums = [1,17,5,10,13,15,10,5,16,8]
Output: 7
Explanation: There are several subsequences that achieve this length.
One is [1, 17, 10, 13, 10, 16, 8] with differences (16, -7, 3, -3, 6, -8).
```

```
Input: nums = [1,2,3,4,5,6,7,8,9]
Output: 2
```

`1 <= nums.length <= 1000`

.`0 <= nums[i] <= 1000`

.

**Follow up**: Could you solve this in `O(n)`

time?

`nums`

First, if you pick all local extrema (minima and maxima) of `nums`

to form a subsequence `e`

, then it is wiggle. Let us call it an **extrema** subsequence.

For `nums = [1,17,5,10,13,15,10,5,16,8]`

, the local extrema are `[1,17,5,15,5,16,8]`

. It is wiggle and called **extrema** subsequence.

Note that if `nums.length = n`

then `nums[0]`

and `nums[n - 1]`

are always the first and the last extremum.

Second, given any two successive local extrema `a`

and `b`

, you cannot have any wiggle subsequence between them. Because the elements between them are either monotonic increasing or decreasing.

That proves the extrema subsequence is the longest wiggle one.

```
#include <iostream>
#include <vector>
using namespace std;
int wiggleMaxLength(vector<int>& nums) {
// nums[0] is always the first extremum
// start to find the second extremum
int i = 1;
while (i < nums.size() && nums[i] == nums[i - 1]) {
i++;
}
if (i == nums.size()) {
// all nums[i] are equal
return 1;
}
int sign = nums[i] > nums[i - 1] ? 1 : -1;
int count = 2;
i++;
while (i < nums.size()) {
if ((nums[i] - nums[i - 1]) * sign < 0) {
// nums[i] is an extremum
count++;
sign = -sign;
}
i++;
}
return count;
}
int main() {
vector<int> nums{1,7,4,9,2,5};
cout << wiggleMaxLength(nums) << endl;
nums = {1,17,5,10,13,15,10,5,16,8};
cout << wiggleMaxLength(nums) << endl;
nums = {1,2,3,4,5,6,7,8,9};
cout << wiggleMaxLength(nums) << endl;
}
```

```
Output:
6
7
2
```

Runtime:

`O(n)`

, where`n = nums.length`

.Extra space:

`O(1)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given an array of integers `arr`

, return `true`

if and only if it is a valid *mountain array*.

Recall that arr is a **mountain array** if and only if:

`arr.length >= 3`

There exists some

`i`

with`0 < i < arr.length - 1`

such that:`arr[0] < arr[1] < ... < arr[i - 1] < arr[i]`

`arr[i] > arr[i + 1] > ... > arr[arr.length - 1]`

```
Input: arr = [2,1]
Output: false
```

```
Input: arr = [3,5,5]
Output: false
```

```
Input: arr = [0,3,2,1]
Output: true
```

`1 <= arr.length <= 10^4`

.`0 <= arr[i] <= 10^4`

.

Following the conditions, we have the following implementation.

```
#include <vector>
#include <iostream>
using namespace std;
bool validMountainArray(vector<int>& arr) {
if (arr.size() < 3) {
return false;
}
const int N = arr.size() - 1;
int i = 0;
while (i < N && arr[i] < arr[i + 1]) {
i++;
}
if (i == 0 || i == N) {
return false;
}
while (i < N && arr[i] > arr[i + 1]) {
i++;
}
return i == N;
}
int main() {
vector<int> arr{2,1};
cout << validMountainArray(arr) << endl;
arr = {3,5,5};
cout << validMountainArray(arr) << endl;
arr = {0,3,2,1};
cout << validMountainArray(arr) << endl;
arr = {9,8,7,6,5,4,3,2,1,0};
cout << validMountainArray(arr) << endl;
}
```

```
Output:
0
0
1
0
```

Runtime:

`O(N)`

, where`N = arr.length`

.Extra space:

`O(1)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given an array of integers `nums`

containing `n + 1`

integers where each integer is in the range `[1, n]`

inclusive.

There is only one repeated number in `nums`

, return this repeated number.

You must solve the problem without modifying the array `nums`

and uses only constant extra space.

```
Input: nums = [1,3,4,2,2]
Output: 2
```

```
Input: nums = [3,1,3,4,2]
Output: 3
```

`1 <= n <= 10^5`

.`nums.length == n + 1`

.`1 <= nums[i] <= n`

.All the integers in

`nums`

appear only once except for precisely one integer which appears two or more times.

**Follow up**:

How can we prove that at least one duplicate number must exist in

`nums`

?Can you solve the problem in linear runtime complexity?

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int findDuplicate(vector<int>& nums) {
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size() - 1; i++) {
if (nums[i] == nums[i + 1]) {
return nums[i];
}
}
return 0;
}
int main() {
vector<int> nums{1,3,4,2,2};
cout << findDuplicate(nums) << endl;
nums = {3,1,3,4,2};
cout << findDuplicate(nums) << endl;
}
```

```
Output:
2
3
```

Runtime:

`O(NlogN)`

, where`N = nums.length`

.Extra space:

`O(1)`

.

`nums`

?Due to Pigeonhole principle:

Here there are `n + 1`

pigeons in `n`

holes. The pigeonhole principle says that at least one hole has more than one pigeon.

Here are a few solutions.

```
#include <vector>
#include <iostream>
using namespace std;
int findDuplicate(vector<int>& nums) {
vector<bool> visited(nums.size());
for (int a : nums) {
if (visited[a]) {
return a;
}
visited[a] = true;
}
return 0;
}
int main() {
vector<int> nums{1,3,4,2,2};
cout << findDuplicate(nums) << endl;
nums = {3,1,3,4,2};
cout << findDuplicate(nums) << endl;
}
```

```
Output:
2
3
```

Runtime:

`O(N)`

, where`N = nums.length`

.Extra space:

`O(logN)`

.`std::vector<bool>`

is optimized for space-efficient.

`std::bitset`

Since `n <= 10^5`

, you can use this size for a `std::bitset`

to do the marking.

```
#include <vector>
#include <iostream>
#include <bitset>
using namespace std;
int findDuplicate(vector<int>& nums) {
bitset<100001> visited;
for (int a : nums) {
if (visited[a]) {
return a;
}
visited[a] = 1;
}
return 0;
}
int main() {
vector<int> nums{1,3,4,2,2};
cout << findDuplicate(nums) << endl;
nums = {3,1,3,4,2};
cout << findDuplicate(nums) << endl;
}
```

```
Output:
2
3
```

Runtime:

`O(N)`

, where`N = nums.length`

.Extra space:

`O(1)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given a string `columnTitle`

that represents the column title as appears in an Excel sheet, return its corresponding column number.

For example:

```
A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28
...
```

```
Input: columnTitle = "A"
Output: 1
```

```
Input: columnTitle = "AB"
Output: 28
```

```
Input: columnTitle = "ZY"
Output: 701
```

`1 <= columnTitle.length <= 7`

.`columnTitle`

consists only of uppercase English letters.`columnTitle`

is in the range`["A", "FXSHRXW"]`

.

Let us write down some other `columnTitle`

strings and its value.

```
"A" = 1
"Z" = 26
"AA" = 27
"AZ" = 52
"ZZ" = 702
"AAA" = 703
```

Then try to find the pattern

```
"A" = 1 = 1
"Z" = 26 = 26
"AA" = 27 = 26 + 1
"AZ" = 52 = 26 + 26
"ZZ" = 702 = 26*26 + 26
"AAA" = 703 = 26*26 + 26 + 1
```

If you map `'A' = 1, ..., 'Z' = 26`

, the values can be rewritten as

```
"A" = 1 = 'A'
"Z" = 26 = 'Z'
"AA" = 27 = 26*'A' + 'A'
"AZ" = 52 = 26*'A' + 'Z'
"ZZ" = 702 = 26*'Z' + 'Z'
"AAA" = 703 = 26*26*'A' + 26*'A' + 'A'
```

In general the formula for a string `columnTitle = abcd`

is

```
abcd = 26^3*a + 26^2*b + 26*c + d,
```

where `a, b, c, d`

are some uppercase English letters `A, ..., Z`

.

Longer `columnTitle`

s will have bigger leading exponents of `26`

.

```
#include <iostream>
using namespace std;
int titleToNumber(string columnTitle) {
int column = 0;
for (char c : columnTitle) {
// The ASCII value of 'A' is 65.
column = 26*column + (c - 64);
}
return column;
}
int main() {
cout << titleToNumber("A") << endl;
cout << titleToNumber("AB") << endl;
cout << titleToNumber("ZY") << endl;
}
```

```
Output:
1
28
701
```

Runtime:

`O(N)`

, where`N = columnTitle.length`

.Extra space:

`O(1)`

.

There are many ways to compute the series

`26^3*a + 26^2*b + 26*c + d.`

If you write it as

`26*(26*(26*(0 + a) + b) + c) + d,`

you get the loop in the code above.

To map

`'A' = 1, ..., 'Z' = 26`

, you can use their ASCII values (`'A' = 65, ..., 'Z' = 90`

) minus`64`

.The parentheses around

`(c - 64)`

is needed. Otherwise the value of`columnTitle = "FXSHRXW"`

makes`26*column + c`

exceed the limit of`int`

before it substracts`64`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given an integer `n`

, return the decimal value of the binary string formed by concatenating the binary representations of `1`

to `n`

in order, modulo `10^9 + 7`

.

```
Input: n = 1
Output: 1
Explanation: "1" in binary corresponds to the decimal value 1.
```

```
Input: n = 3
Output: 27
Explanation: In binary, 1, 2, and 3 corresponds to "1", "10", and "11".
After concatenating them, we have "11011", which corresponds to the decimal value 27.
```

```
Input: n = 12
Output: 505379714
Explanation: The concatenation results in "1101110010111011110001001101010111100".
The decimal value of that is 118505380540.
After modulo 10^9 + 7, the result is 505379714.
```

`1 <= n <= 10^5`

.

There must be some relationship between the result of `n`

and the result of `n - 1`

.

First, let us list some first values of `n`

.

For

`n = 1`

: the final binary string is`"1"`

, its decimal value is`1`

.For

`n = 2`

: the final binary string is`"110"`

, its decimal value is`6`

.For

`n = 3`

: the final binary string is`"11011"`

, its decimal value is`27`

.

Look at `n = 3`

, you can see the relationship between the decimal value of `"11011"`

and the one of `"110"`

(of `n = 2`

) is:

```
27 = 6 * 2^2 + 3
Dec("11011") = Dec("110") * 2^num_bits("11") + Dec("11")
Result(3) = Result(2) * 2^num_bits(3) + 3.
```

The same equation for `n = 2`

:

```
6 = 1 * 2^2 + 2
Dec("110") = Dec("1") * 2^num_bits("10") + Dec("10")
Result(2) = Result(1) * 2^num_bits(2) + 2.
```

In general, the recursive relationship between `n`

and `n - 1`

is:

```
Result(n) = Result(n - 1) * 2^num_bits(n) + n.
```

```
#include <cmath>
#include <iostream>
int concatenatedBinary(int n) {
unsigned long long result = 1;
for (int i = 2; i <= n; i++) {
const int num_bits = std::log2(i) + 1;
result = ((result << num_bits) + i) % 1000000007;
}
return result;
}
int main() {
std::cout << concatenatedBinary(1) << std::endl;
std::cout << concatenatedBinary(3) << std::endl;
std::cout << concatenatedBinary(12) << std::endl;
}
```

```
Output:
1
27
505379714
```

Runtime:

`O(n)`

.Extra space:

`O(1)`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given an array `nums`

of size `n`

, return the majority element.

The majority element is the element that appears more than `n / 2`

times. You may assume that the majority element always exists in the array.

```
Input: nums = [3,2,3]
Output: 3
```

```
Input: nums = [2,2,1,1,1,2,2]
Output: 2
```

`n == nums.length`

.`1 <= n <= 5 * 10^4`

.`-2^31 <= nums[i] <= 2^31 - 1`

.

Could you solve the problem in linear time and in `O(1)`

space?

```
#include <vector>
#include <iostream>
#include <unordered_map>
using namespace std;
int majorityElement(vector<int>& nums) {
unordered_map<int,int> freq;
const int HALF = nums.size() / 2;
for (int a : nums) {
freq[a]++;
if (freq[a] > HALF) {
return a;
}
}
return nums[0];
}
int main() {
vector<int> nums{3,2,3};
cout << majorityElement(nums) << endl;
nums = {2,2,1,1,1,2,2};
cout << majorityElement(nums) << endl;
}
```

```
Output:
3
2
```

Runtime:

`O(n)`

, where`n = nums.length`

.Extra space:

`O(n)`

.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int majorityElement(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nums[nums.size()/2];
}
int main() {
vector<int> nums{3,2,3};
cout << majorityElement(nums) << endl;
nums = {2,2,1,1,1,2,2};
cout << majorityElement(nums) << endl;
}
```

```
Output:
3
2
```

Runtime:

`O(nlogn)`

, where`n = nums.length`

.Extra space:

`O(1)`

.

Since you are interested in only the middle element after sorting, the partial sorting algorithm `std::nth_element`

can be used in this case to reduce the cost of the full sorting.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int majorityElement(vector<int>& nums) {
const int mid = nums.size() / 2;
std::nth_element(nums.begin(), nums.begin() + mid, nums.end());
return nums[mid];
}
int main() {
vector<int> nums{3,2,3};
cout << majorityElement(nums) << endl; // 3
nums = {2,2,1,1,1,2,2};
cout << majorityElement(nums) << endl; // 2
}
```

```
Output:
3
2
```

Runtime:

`O(n)`

, where`n = nums.length`

.Extra space:

`O(1)`

.

In the code of Solution 3, the partial sorting algorithm `std::nth_element`

will make sure for all indices `i`

and `j`

that satisfy `0 <= i <= mid <= j < nums.length`

,

```
nums[i] <= nums[mid] <= nums[j].
```

In other words, `nums[mid]`

divides the array `nums`

into two groups: all elements that are less than or equal to `nums[mid]`

and the ones that are greater than or equal to `nums[mid]`

.

Those two groups are unsorted. That is why the algorithm is called *partial* sorting.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

A decimal number is called deci-binary if each of its digits is either `0`

or `1`

without any leading zeros. For example, `101`

and `1100`

are deci-binary, while `112`

and `3001`

are not.

Given a string `n`

that represents a positive decimal integer, return the minimum number of positive deci-binary numbers needed so that they sum up to `n`

.

```
Input: n = "32"
Output: 3
Explanation: 10 + 11 + 11 = 32
```

```
Input: n = "82734"
Output: 8
```

```
Input: n = "27346209830709182346"
Output: 9
```

`1 <= n.length <= 10^5`

.`n`

consists of only digits.`n`

does not contain any leading zeros and represents a positive integer.

`n`

Any digit `d`

can be obtained by summing the digit `1`

`d`

times.

The problem turns into identifying the maximum digit of `n`

.

For `n = "82734"`

the answer is 8 because:

```
82734
= 11111
+ 11111
+ 10111
+ 10101
+ 10100
+ 10100
+ 10100
+ 10000
```

```
#include <iostream>
using namespace std;
int minPartitions(string n) {
char maxDigit = '0';
for (char& d : n) {
maxDigit = max(maxDigit, d);
}
return maxDigit - '0';
}
int main() {
cout << minPartitions("32") << endl;
cout << minPartitions("82734") << endl;
cout << minPartitions("27346209830709182346") << endl;
}
```

```
Output:
3
8
9
```

Runtime:

`O(N)`

, where`N = n.length`

.Extra space:

`O(1)`

.

You are given an array `target`

of `n`

integers. From a starting array `arr`

consisting of `n`

1's, you may perform the following procedure:

Let

`x`

be the sum of all elements currently in your array`arr`

.Choose any index

`i`

such that`0 <= i < n`

and set the value`arr[i] = x`

.You may repeat this procedure as many times as needed.

Return `true`

if it is possible to construct the `target`

array from `arr`

, otherwise, return `false`

.

```
Input: target = [9,3,5]
Output: true
Explanation: Start with arr = [1, 1, 1]
[1, 1, 1], sum = 3 choose index 1
[1, 3, 1], sum = 5 choose index 2
[1, 3, 5], sum = 9 choose index 0
[9, 3, 5] Done
```

```
Input: target = [1,1,1,2]
Output: false
Explanation: Impossible to create target array from [1,1,1,1].
```

```
Input: target = [8,5]
Output: true
```

`n == target.length`

.`1 <= n <= 5 * 10^4`

.`1 <= target[i] <= 10^9`

.

If you start from `arr = [1,1,...,1]`

and follow the required procedure, the new element `x`

you get for the next state is always the max element of `arr`

.

To solve this problem, you can start from the max element of the given `target`

to compute its previous state until you get the `arr = [1,1,...,1]`

.

For `target = [9,3,5]`

:

The max element is

`9`

, subtract it from the remaining sum:`9 - (3 + 5) = 1`

, you get`target = [1,3,5]`

.The max element is

`5`

, subtract it from the remaining sum:`5 - (1 + 3) = 1`

, you get`target = [1,3,1]`

.The max element is

`3`

, subtract it from the remaining sum:`3 - (1 + 1) = 1`

, you get`target = [1,1,1]`

.Return

`true`

.

If

`target = [m,1]`

or`target = [1,m]`

for any`m >= 1`

, you can always turn it to`arr = [1,1]`

.If the changed value after the subtraction is still the max element of the previous state, you need to redo the subtraction at the same position. In this case, the modulo might be used instead of subtraction.

```
#include <iostream>
#include <numeric>
#include <algorithm>
#include <vector>
using namespace std;
bool isPossible(vector<int>& target) {
unsigned long sum = accumulate(target.begin(), target.end(), (unsigned long) 0);
auto pmax = max_element(target.begin(), target.end());
while (*pmax > 1) {
sum -= *pmax;
if (sum == 1) {
// This is the case target = [m,1], which you can always turn it to [1,1].
return true;
}
if (*pmax <= sum) {
return false;
}
if (sum == 0) {
return false;
}
*pmax %= sum;
if (*pmax == 0) {
return false;
}
sum += *pmax;
pmax = max_element(target.begin(), target.end());
}
return sum == target.size();
}
int main() {
vector<int> target{9,3,5};
cout << isPossible(target) << endl;
target = {1,1,1,2};
cout << isPossible(target) << endl;
target = {8,5};
cout << isPossible(target) << endl;
}
```

```
Output:
1
0
1
```

Runtime:

`O(logN)`

, where`N = max(target)`

.Extra space:

`O(1)`

.

In the solution above, the position of the max element in each state is not so important as long as you update exactly it, not the other ones.

That might lead to the usage of the std::priority_queue.

```
#include <iostream>
#include <numeric>
#include <queue>
#include <vector>
using namespace std;
bool isPossible(vector<int>& target) {
priority_queue<int> q(target.begin(), target.end());
unsigned long sum = accumulate(target.begin(), target.end(), (unsigned long) 0);
while (q.top() > 1) {
sum -= q.top();
if (sum == 1) {
return true;
}
if (q.top() <= sum) {
return false;
}
if (sum == 0) {
return false;
}
int pre = q.top() % sum;
if (pre == 0) {
return false;
}
q.pop();
q.push(pre);
sum += pre;
}
return sum == target.size();
}
int main() {
vector<int> target{9,3,5};
cout << isPossible(target) << endl;
target = {1,1,1,2};
cout << isPossible(target) << endl;
target = {8,5};
cout << isPossible(target) << endl;
}
```

```
Output:
1
0
1
```

Runtime:

`O(logN)`

, where`N = max(target)`

.Extra space:

`O(n)`

, where`n = target.length`

.

*Thanks for reading. Feel free to share your thought about my content and check out my* *FREE book 10 Classic Coding Challenges**.*

Given a `triangle`

array, return the minimum path sum from top to bottom.

For each step, you may move to an adjacent number of the row below. More formally, if you are on index `i`

on the current row, you may move to either index `i`

or index `i + 1`

on the next row.

```
Input: triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
Output: 11
Explanation: The triangle looks like:
2
3 4
6 5 7
4 1 8 3
The minimum path sum from top to bottom is 2 + 3 + 5 + 1 = 11 (underlined above).
```

```
Input: triangle = [[-10]]
Output: -10
```

`1 <= triangle.length <= 200`

.`triangle[0].length == 1`

.`triangle[i].length == triangle[i - 1].length + 1`

.`-10^4 <= triangle[i][j] <= 10^4`

.

**Follow up**: Could you do this using only `O(n)`

extra space, where `n`

is the total number of rows in the triangle?

You can store all minimum paths at every positions `(i,j)`

so you can compute the next ones with this relationship.

```
minTotal[i][j] = triangle[i][j] + min(minTotal[i - 1][j - 1], minTotal[i - 1][j]);
```

```
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int minimumTotal(vector<vector<int>>& triangle) {
vector<vector<int>> minTotal(triangle.size());
minTotal[0] = triangle[0];
for (int i = 1; i < triangle.size(); i++) {
const int N = triangle[i].size();
minTotal[i].resize(N);
for (int j = 0; j < N; j++) {
if (j == 0) {
minTotal[i][j] = triangle[i][j] + minTotal[i - 1][j];
} else if (j == N - 1) {
minTotal[i][j] = triangle[i][j] + minTotal[i - 1][j - 1];
} else {
minTotal[i][j] = triangle[i][j] + min(minTotal[i - 1][j - 1], minTotal[i - 1][j]);
}
}
}
return *min_element(minTotal[triangle.size() - 1].begin(), minTotal[triangle.size() - 1].end());
}
int main() {
vector<vector<int>> triangle{{2},{3,4},{6,5,7},{4,1,8,3}};
cout << minimumTotal(triangle) << endl;
triangle = {{-10}};
cout << minimumTotal(triangle) << endl;
}
```

```
Output:
11
-10
```

Runtime:

`O(n*n/2)`

, where`n = triangle.length`

.Extra space:

`O(n*n/2)`

.

You do not need to store all paths for all rows. The computation of the next row only depends on its previous one.

```
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int minimumTotal(vector<vector<int>>& triangle) {
vector<int> minTotal(triangle.size());
minTotal[0] = triangle[0][0];
for (int i = 1; i < triangle.size(); i++) {
minTotal[i] = triangle[i][i] + minTotal[i - 1];
for (int j = i - 1; j > 0; j--) {
minTotal[j] = triangle[i][j] + min(minTotal[j - 1], minTotal[j]);
}
minTotal[0] = triangle[i][0] + minTotal[0];
}
return *min_element(minTotal.begin(), minTotal.end());
}
int main() {
vector<vector<int>> triangle{{2},{3,4},{6,5,7},{4,1,8,3}};
cout << minimumTotal(triangle) << endl;
triangle = {{-10}};
cout << minimumTotal(triangle) << endl;
}
```

```
Output:
11
-10
```

Runtime:

`O(n*n/2)`

, where`n = triangle.length`

.Extra space:

`O(n)`

.

You are given an array of positive integers `nums`

and want to erase a subarray containing unique elements. The score you get by erasing the subarray is equal to the sum of its elements.

Return the maximum score you can get by erasing exactly one subarray.

An array `b`

is called to be a subarray of `a`

if it forms a contiguous subsequence of `a`

, that is, if it is equal to `a[l],a[l+1],...,a[r]`

for some `(l,r)`

.

```
Input: nums = [4,2,4,5,6]
Output: 17
Explanation: The optimal subarray here is [2,4,5,6].
```

```
Input: nums = [5,2,1,2,5,2,1,2,5]
Output: 8
Explanation: The optimal subarray here is [5,2,1] or [1,2,5].
```

`1 <= nums.length <= 10^5`

.`1 <= nums[i] <= 10^4`

.

You can use a map to store the position of the elements of `nums`

. Then when iterating `nums`

you can identify if an element has been visited before. That helps you to decide if a subarray contains unique elements.

```
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
int maximumUniqueSubarray(vector<int>& nums) {
vector<int> sum(nums.size(), 0);
sum[0] = nums[0];
int maxSum = sum[0];
unordered_map<int, int> position;
position[nums[0]] = 0;
int start = -1;
for (int i = 1; i < nums.size(); i++) {
sum[i] = sum[i - 1] + nums[i];
if (position.find(nums[i]) != position.end()) {
start = max(start, position[nums[i]]);
}
position[nums[i]] = i;
maxSum = (start == -1) ? sum[i] : max(maxSum, sum[i] - sum[start]);
}
return maxSum;
}
int main() {
vector<int> nums{4,2,4,5,6};
cout << maximumUniqueSubarray(nums) << endl;
nums = {5,2,1,2,5,2,1,2,5};
cout << maximumUniqueSubarray(nums) << endl;
}
```

```
Output:
17
8
```

Runtime:

`O(N)`

, where`N = nums.length`

.Extra space:

`O(N)`

.

Given an integer `n`

, return `true`

if it is a power of four. Otherwise, return `false`

.

An integer `n`

is a power of four if there exists an integer `x`

such that `n == 4^x`

.

```
Input: n = 16
Output: true
```

```
Input: n = 5
Output: false
```

```
Input: n = 1
Output: true
```

`-2^31 <= n <= 2^31 - 1`

.

**Follow up**: Could you solve it without loops/recursion?

```
#include <iostream>
using namespace std;
bool isPowerOfFour(int n) {
while (n % 4 == 0 && n > 0) {
n /= 4;
}
return n == 1;
}
int main() {
cout << isPowerOfFour(16) << endl;
cout << isPowerOfFour(5) << endl;
cout << isPowerOfFour(1) << endl;
}
```

```
Output:
1
0
1
```

Runtime:

`O(logn)`

.Extra space:

`O(1)`

.

You can write down the binary representation of the powers of four to find the pattern.

```
1 : 1
4 : 100
16 : 10000
64 : 1000000
256 : 100000000
...
```

You might notice the patterns are **n is a positive integer having only one bit** `1`

in its binary representation and it is located at the odd positions (starting from the right).

How can you formulate those conditions?

If `n`

has only one bit `1`

in its binary representation `10...0`

, then `n - 1`

has the complete opposite binary representation `01...1`

.

You can use the bit operator AND to formulate this condition

```
n & (n - 1) == 0
```

Let `A`

be the number whose binary representation has only bits `1`

at all odd positions, then `n & A`

is never `0`

.

In this problem, `A < 2^31`

. You can choose`A = 0x55555555`

, the hexadecimal of `0101 0101 0101 0101 0101 0101 0101 0101`

.

```
#include <iostream>
using namespace std;
bool isPowerOfFour(int n) {
return n > 0 && (n & (n - 1)) == 0 && (n & 0x55555555) != 0;
}
int main() {
cout << isPowerOfFour(16) << endl;
cout << isPowerOfFour(5) << endl;
cout << isPowerOfFour(1) << endl;
}
```

```
Output:
1
0
1
```

Runtime:

`O(1)`

.Extra space:

`O(1)`

.

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

```
Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807.
```

```
Input: l1 = [0], l2 = [0]
Output: [0]
```

```
Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
Output: [8,9,9,9,0,0,0,1]
```

The number of nodes in each linked list is in the range

`[1, 100]`

.`0 <= Node.val <= 9`

.It is guaranteed that the list represents a number that does not have leading zeros.

Perform the school addition calculation and store the result in one of the lists.

Without loss of generality, let us store the result in `l1`

. Then you might need to extend it when `l2`

is longer than `l1`

and when the result requires one additional node (Example 3).

```
#include <iostream>
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode prehead; // dummy node to hook the head of the list
ListNode* node = l1; // store result on l1
prehead.next = node;
int sum = 0;
while (node) {
if (l1) {
sum += l1->val;
l1 = l1->next;
}
if (l2) {
sum += l2->val;
l2 = l2->next;
}
node->val = sum % 10;
sum /= 10;
if (!l1) { // l1 ends
if (l2) { // l1 is shorter than l2
node->next = l2;
} else if (sum == 1) { // both l1 and l2 end but the remember is not zero
ListNode* newNode = new ListNode(sum);
node->next = newNode;
}
}
node = node->next;
}
return prehead.next;
}
void printResult(ListNode* l) {
std::cout << "[";
while (l) {
std::cout << l->val << ",";
l = l->next;
}
std::cout << "]\n";
}
int main() {
{
ListNode three(3);
ListNode four1(4, &three);
ListNode two(2, &four1);
ListNode four2(4);
ListNode six(6, &four2);
ListNode five(5, &six);
printResult(addTwoNumbers(&two, &five));
}
{
ListNode zero1(0);
ListNode zero2(0);
printResult(addTwoNumbers(&zero1, &zero2));
}
{
ListNode nine0(9);
ListNode nine1(9, &nine0);
ListNode nine2(9, &nine1);
ListNode nine3(9, &nine2);
ListNode nine4(9, &nine3);
ListNode nine5(9, &nine4);
ListNode nine6(9, &nine5);
ListNode nine7(9);
ListNode nine8(9, &nine7);
ListNode nine9(9, &nine8);
ListNode nine10(9, &nine9);
printResult(addTwoNumbers(&nine6, &nine10));
}
}
```

```
Output:
[7,0,8,]
[0,]
[8,9,9,9,0,0,0,1,]
```

Runtime:

`O(N)`

, where`N = max(l1.length, l2.length)`

.Extra space:

`O(1)`

.

Given a string `s`

, find the first non-repeating character in it and return its index. If it does not exist, return `-1`

.

```
Input: s = "leetcode"
Output: 0
```

```
Input: s = "loveleetcode"
Output: 2
```

```
Input: s = "aabb"
Output: -1
```

`1 <= s.length <= 10^5`

.`s`

consists of only lowercase English letters.

```
#include <iostream>
#include <unordered_map>
using namespace std;
int firstUniqChar(string s) {
unordered_map<char, int> count;
for (char& c : s) {
count[c]++;
}
for (int i = 0; i < s.length(); i++) {
if (count[s[i]] == 1) {
return i;
}
}
return -1;
}
int main() {
cout << firstUniqChar("leetcode") << endl;
cout << firstUniqChar("loveleetcode") << endl;
cout << firstUniqChar("aabb") << endl;
}
```

```
Output:
0
2
-1
```

Runtime:

`O(N)`

, where`N = s.length`

.Extra space:

`O(1)`

if`N`

is very larger than`26`

.

```
#include <iostream>
#include <vector>
using namespace std;
int firstUniqChar(string s) {
vector<int> count(26);
for (char& c : s) {
count[c - 'a']++;
}
for (int i = 0; i < s.length(); i++) {
if (count[s[i] - 'a'] == 1) {
return i;
}
}
return -1;
}
int main() {
cout << firstUniqChar("leetcode") << endl;
cout << firstUniqChar("loveleetcode") << endl;
cout << firstUniqChar("aabb") << endl;
}
```

```
Output:
0
2
-1
```

Runtime:

`O(N)`

, where`N = s.length`

.Extra space:

`O(1)`

if`N`

is very larger than`26`

.

10 selected coding challenges in the tech interviews of companies like Facebook, Amazon, Apple, Netflix, or Google.

Full explanations of how to solve the problems.

C++ programming tips.

Runtime and memory complexity analysis.

You will get my eBook in PDF of 47 pages long.

Get it on Gumroad and enjoy your reading!

]]>Given a binary search tree (BST), find the lowest common ancestor (LCA) node of two given nodes in the BST.

According to the definition of LCA on Wikipedia: "The lowest common ancestor is defined between two nodes `p`

and `q`

as the lowest node in `T`

that has both `p`

and `q`

as descendants (where we allow a node to be a descendant of itself)."

```
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output: 6
Explanation: The LCA of nodes 2 and 8 is 6.
```

```
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
Output: 2
Explanation: The LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
```

```
Input: root = [2,1], p = 2, q = 1
Output: 2
```

The number of nodes in the tree is in the range

`[2, 10^5]`

.`-10^9 <= Node.val <= 10^9`

.All

`Node.val`

are unique.`p != q`

.`p`

and`q`

will exist in the BST.

Note that in a BST, the values of a `node`

and its children `left`

and `right`

satisfy

```
left.value < node.value < right.value.
```

It lets you know which branch (left or right) of the `root`

the nodes `p`

and `q`

belong to.

```
#include <iostream>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (p->val < root->val && q->val < root->val) {
return lowestCommonAncestor(root->left, p, q);
} else if (root->val < p->val && root->val < q->val) {
return lowestCommonAncestor(root->right, p, q);
}
return root;
}
int main() {
TreeNode zero(0);
TreeNode three(3);
TreeNode five(5);
TreeNode four(4);
four.left = &three;
four.right = &five;
TreeNode two(2);
two.left = &zero;
two.right = &four;
TreeNode seven(7);
TreeNode nine(9);
TreeNode eight(8);
eight.left = &seven;
eight.right = &nine;
TreeNode six(6);
six.left = &two;
six.right = &eight;
cout << lowestCommonAncestor(&six, &two, &eight)->val << endl;
cout << lowestCommonAncestor(&six, &two, &four)->val << endl;
cout << lowestCommonAncestor(&two, &two, &zero)->val << endl;
}
```

```
Output:
6
2
2
```

Runtime:

`O(logN)`

(the height of the tree), where`N`

is the number of nodes.Extra space:

`O(1)`

.

Given an `n x n`

matrix where each of the rows and columns is sorted in ascending order, return the `k-th`

smallest element in the matrix.

Note that it is the `k-th`

smallest element in the sorted order, not the `k-th`

distinct element.

You must find a solution with a memory complexity better than `O(n^2)`

.

```
Input: matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8
Output: 13
Explanation: The elements in the matrix are [1,5,9,10,11,12,13,13,15], and the 8th smallest number is 13
```

```
Input: matrix = [[-5]], k = 1
Output: -5
```

`n == matrix.length == matrix[i].length`

.`1 <= n <= 300`

.`-10^9 <= matrix[i][j] <= 10^9`

.All the rows and columns of

`matrix`

are guaranteed to be sorted in non-decreasing order.`1 <= k <= n^2`

.

Could you solve the problem with a constant memory (i.e.,

`O(1)`

memory complexity)?Could you solve the problem in

`O(n)`

time complexity? The solution may be too advanced for an interview but you may find reading this paper fun.

You can implement exactly what Example 1 has explained.

```
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int kthSmallest(vector<vector<int>>& matrix, int k) {
vector<int> m;
for (auto& row : matrix) {
m.insert(m.end(), row.begin(), row.end());
}
sort(m.begin(), m.end());
return m[k - 1];
}
int main() {
vector<vector<int>> matrix{{1,5,9},{10,11,13},{12,13,15}};
cout << kthSmallest(matrix, 8) << endl;
matrix = {{-5}};
cout << kthSmallest(matrix, 1) << endl;
}
```

```
Output:
13
-5
```

Runtime:

`O(n^2*logn)`

, where`n x n`

is the size of the matrix. Note that`log(n^2) = 2logn`

.Extra space:

`O(n^2)`

.

Instead of sorting after building the vector in Solution 1, you can do the other way around. It means building up the vector from scratch and keeping it sorted.

Since you need only the `k-th`

smallest element, `std::priority_queue`

can be used for this purpose.

```
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int kthSmallest(vector<vector<int>>& matrix, int k) {
priority_queue<int> q;
for (int row = 0; row < matrix.size(); row++) {
for (int col = 0; col < matrix[row].size(); col++) {
q.push(matrix[row][col]);
if (q.size() > k) {
q.pop();
}
}
}
return q.top();
}
int main() {
vector<vector<int>> matrix{{1,5,9},{10,11,13},{12,13,15}};
cout << kthSmallest(matrix, 8) << endl;
matrix = {{-5}};
cout << kthSmallest(matrix, 1) << endl;
}
```

```
Output:
13
-5
```

Runtime:

`O(n^2*logk)`

, where`n x n`

is the size of the matrix.Extra space:

`O(k)`

.

Since the matrix is somehow sorted, you can perform the binary search algorithm on it.

But the criteria for the searching is not the value of the element `x`

of interest; it is the number of elements that less than or equal to `x`

must be exactly `k`

. You can use `std::upper_bound`

for this purpose.

```
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int countLessOrEqual(const vector<vector<int>>& matrix, int x) {
int count = 0;
for (const auto& row : matrix) {
count += upper_bound(row.begin(), row.end(), x) - row.begin();
}
return count;
}
int kthSmallest(vector<vector<int>>& matrix, int k) {
int left = matrix.front().front();
int right = matrix.back().back();
while (left <= right) {
int mid = left + (right - left) / 2;
if (countLessOrEqual(matrix, mid) >= k) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
}
int main() {
vector<vector<int>> matrix{{1,5,9},{10,11,13},{12,13,15}};
cout << kthSmallest(matrix, 8) << endl;
matrix = {{-5}};
cout << kthSmallest(matrix, 1) << endl;
}
```

```
Output:
13
-5
```

Runtime:

`O(nlognlogM)`

, where`n x n`

is the size of the matrix,`M`

is the difference between the maximum element and the minimum element of the matrix.Extra space:

`O(1)`

.

Given a list of strings `words`

and a string `pattern`

, return a list of `words[i]`

that match `pattern`

. You may return the answer in any order.

A word matches the pattern if there exists a permutation of letters `p`

so that after replacing every letter `x`

in the pattern with `p(x)`

, we get the desired word.

Recall that a permutation of letters is a bijection from letters to letters: every letter maps to another letter, and no two letters map to the same letter.

```
Input: words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"
Output: ["mee","aqq"]
Explanation: "mee" matches the pattern because there is a permutation {a -> m, b -> e, ...}.
"ccc" does not match the pattern because {a -> c, b -> c, ...} is not a permutation, since a and b map to the same letter.
```

```
Input: words = ["a","b","c"], pattern = "a"
Output: ["a","b","c"]
```

`1 <= pattern.length <= 20`

.`1 <= words.length <= 50`

.`words[i].length == pattern.length`

.`pattern`

and`words[i]`

are lowercase English letters.

```
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
vector<string> findAndReplacePattern(vector<string>& words, string pattern) {
vector<string> result;
// need two maps for the bijection
unordered_map<char,char> w_to_p, p_to_w;
int i;
for (string& w : words) {
w_to_p.clear();
p_to_w.clear();
i = 0;
while (i < w.length()) {
if (w_to_p.find(w[i]) != w_to_p.end()) {
// w[i] was mapped to some letter x
// but x != pattern[i]
if (w_to_p[w[i]] != pattern[i]) {
break;
}
} else {
if (p_to_w.find(pattern[i]) != p_to_w.end()) {
// w[i] was not mapped to any letter yet
// but pattern[i] was already mapped to some letter
break;
}
// build the bijection w[i] <-> pattern[i]
w_to_p[w[i]] = pattern[i];
p_to_w[pattern[i]] = w[i];
}
i++;
}
if (i == w.length()) {
result.push_back(w);
}
}
return result;
}
void printResult(const vector<string>& result) {
cout << "[";
for (const string& s : result) {
cout << s << ",";
}
cout << "]\n";
}
int main() {
vector<string> words{"abc","deq","mee","aqq","dkd","ccc"};
auto result = findAndReplacePattern(words, "abb");
printResult(result);
words = {"a", "b", "c"};
result = findAndReplacePattern(words, "abb");
printResult(result);
}
```

```
Output:
[mee,aqq,]
[a,b,c,]
```

Runtime:

`O(N*L)`

, where`N = words.length`

and`L = pattern.length`

.Extra space:

`O(1)`

if`N`

or`L`

is very larger than 26. The maps`w_to_p`

and`p_to_w`

just map between 26 lowercase English letters.

Given a *directed acyclic graph* (DAG) of `n`

nodes labeled from `0`

to `n - 1`

, find all possible paths from node `0`

to node `n - 1`

and return them in any order.

The graph is given as follows: `graph[i]`

is a list of all nodes you can visit from node `i`

(i.e., there is a directed edge from node `i`

to node `graph[i][j]`

).

```
Input: graph = [[1,2],[3],[3],[]]
Output: [[0,1,3],[0,2,3]]
Explanation: There are two paths: `0 -> 1 -> 3` and `0 -> 2 -> 3`.
```

```
Input: graph = [[4,3,1],[3,2,4],[3],[4],[]]
Output: [[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]
```

```
Input: graph = [[1],[]]
Output: [[0,1]]
```

```
Input: graph = [[1,2,3],[2],[3],[]]
Output: [[0,1,2,3],[0,2,3],[0,3]]
```

```
Input: graph = [[1,3],[2],[3],[]]
Output: [[0,1,2,3],[0,3]]
```

`n == graph.length`

.`2 <= n <= 15`

.`0 <= graph[i][j] < n`

.`graph[i][j] != i`

(i.e., there will be no self-loops).All the elements of

`graph[i]`

are unique.The input graph is guaranteed to be a DAG.

This problem is exactly the Depth-first search algorithm.

```
#include <vector>
#include <iostream>
using namespace std;
void DFS(vector<vector<int>>& graph, vector<vector<int>>& paths, vector<int>& path) {
for (auto& node : graph[path.back()]) {
path.push_back(node);
if (node == graph.size() - 1) {
paths.push_back(path);
path.pop_back();
} else {
DFS(graph, paths, path);
}
}
path.pop_back();
}
vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
vector<vector<int>> paths;
vector<int> path = {0};
DFS(graph, paths, path);
return paths;
}
void printPaths(vector<vector<int>>& paths) {
cout << "[";
for (auto& p : paths) {
cout << "[";
for (auto& node : p) {
cout << node << ",";
}
cout << "],";
}
cout << "]\n";
}
int main() {
vector<vector<int>> graph = {{1,2},{3},{3},{}};
auto paths = allPathsSourceTarget(graph);
printPaths(paths);
graph = {{4,3,1},{3,2,4},{3},{4},{}};
paths = allPathsSourceTarget(graph);
printPaths(paths);
}
```

```
Output:
[[0,1,3,],[0,2,3,],]
[[0,4,],[0,3,4,],[0,1,3,4,],[0,1,2,3,4,],[0,1,4,],]
```

Runtime:

`O(N^2)`

, where`N = graph.length`

.Extra space:

`O(N)`

.

Given the `head`

of a singly linked list, return *the middle node of the linked list*.

If there are two middle nodes, return *the second middle* node.

```
Input: head = [1,2,3,4,5]
Output: [3,4,5]
Explanation: The middle node of the list is node 3.
```

```
Input: head = [1,2,3,4,5,6]
Output: [4,5,6]
Explanation: Since the list has two middle nodes with values 3 and 4, we return the second one.
```

The number of nodes in the list is in the range

`[1, 100]`

.`1 <= Node.val <= 100`

.

```
#include <iostream>
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
ListNode* middleNode(ListNode* head) {
ListNode *node = head;
int count = 0;
while (node) {
count++;
node = node->next;
}
int i = 1;
node = head;
while (i <= count/2) {
node = node->next;
i++;
}
return node;
}
void print(ListNode *head) {
ListNode *node = head;
std::cout << "[";
while (node) {
std::cout << node->val << ",";
node = node->next;
}
std::cout << "]\n";
}
int main() {
ListNode five(5);
ListNode four(4, &five);
ListNode three(3, &four);
ListNode two(2, &three);
ListNode one(1, &two);
auto result = middleNode(&one);
print(result);
ListNode six(6);
five.next = &six;
result = middleNode(&one);
print(result);
}
```

```
Output:
[3,4,5,]
[4,5,6,]
```

Runtime:

`O(N + N/2)`

, where`N`

is the number of nodes.Extra space:

`O(1)`

.

Use two pointers to go through the linked list.

One goes one step at a time. The other goes two steps at a time. When the faster reaches the end, the slower reaches the middle.

```
#include <iostream>
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
ListNode* middleNode(ListNode* head) {
ListNode *slow = head;
ListNode *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
void print(ListNode *head) {
ListNode *node = head;
std::cout << "[";
while (node) {
std::cout << node->val << ",";
node = node->next;
}
std::cout << "]\n";
}
int main() {
ListNode five(5);
ListNode four(4, &five);
ListNode three(3, &four);
ListNode two(2, &three);
ListNode one(1, &two);
auto result = middleNode(&one);
print(result);
ListNode six(6);
five.next = &six;
result = middleNode(&one);
print(result);
}
```

```
Output:
[3,4,5,]
[4,5,6,]
```

Runtime:

`O(N/2)`

, where`N`

is the number of nodes.Extra space:

`O(1)`

.

The approach using slow and fast pointers looks very nice and faster. But it is not suitable to generalize this problem to any relative position (one-third, a quarter, etc.). Moreover, long expressions like

`fast->next->...->next`

are not recommended.Though the counting nodes approach does not seem optimized, it is more readable, scalable and maintainable.

You have a long flowerbed in which some of the plots are planted, and some are not. However, flowers cannot be planted in **adjacent** plots.

Given an integer array `flowerbed`

containing `0`

's and `1`

's, where `0`

means empty and `1`

means not empty, and an integer `n`

, return `true`

if `n`

new flowers can be planted in the `flowerbed`

without violating the no-adjacent-flowers rule.

```
Input: flowerbed = [1,0,0,0,1], n = 1
Output: true
```

```
Input: flowerbed = [1,0,0,0,1], n = 2
Output: false
```

`1 <= flowerbed.length <= 2 * 10^4`

.`flowerbed[i]`

is`0`

or`1`

.There are no two adjacent flowers in

`flowerbed`

.`0 <= n <= flowerbed.length`

.

A new flower can be planted at the position `i`

only if

```
flowerbed[i - 1] == 0 && flowerbed[i] == 0 && flowerbed[i + 1] == 0.
```

If the condition is satisfied, the flower can be planted at the position `i`

. `flowerbed[i]`

is now assigned to `1`

. Then you can skip checking the rule for the position `i + 1`

and go directly to the position `i + 2`

.

```
#include <iostream>
#include <vector>
using namespace std;
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
if (n == 0) {
return true;
}
flowerbed.insert(flowerbed.begin(), 0);
flowerbed.push_back(0);
int i = 1;
while (i < flowerbed.size() - 1) {
if (flowerbed[i - 1] == 0 && flowerbed[i] == 0 && flowerbed[i + 1] == 0) {
flowerbed[i] = 1;
n--;
i+=2;
} else {
i++;
}
}
return false;
}
int main() {
vector<int> flowerbed{1,0,0,0,1};
cout << canPlaceFlowers(flowerbed, 1) << endl;
flowerbed = {1,0,0,0,1};
cout << canPlaceFlowers(flowerbed, 2) << endl;
}
```

```
Output:
1
0
```

Runtime:

`O(N)`

, where`N = flowerbed.length`

.Extra space:

`O(1)`

.

In this implementation, you could insert an element

`0`

to the front and the back of the vector`flowerbed`

to avoid writing extra code for checking the no-adjacent-flowers rule at`i = 0`

and`i = flowerbed.size() - 1`

.There are a few ways to insert an element into a vector. Here you can see an example of using the methods

`insert`

and`push_back`

of a`std::vector`

.

*What is your approach? The problem was picked from* *leetcode.com**. You can submit your solution in any programming language and check the performance.*

*Thanks for reading. Feel free to share your thought about my content and check out my FREE book* *10 Classic Coding Challenges**.*

You are given an integer array `nums`

and an integer `k`

.

In one operation, you can pick two numbers from the array whose sum equals `k`

and remove them from the array.

Return the maximum number of operations you can perform on the array.

```
Input: nums = [1,2,3,4], k = 5
Output: 2
Explanation: Starting with nums = [1,2,3,4]:
- Remove numbers 1 and 4, then nums = [2,3]
- Remove numbers 2 and 3, then nums = []
There are no more pairs that sum up to 5, hence a total of 2 operations.
```

```
Input: nums = [3,1,3,4,3], k = 6
Output: 1
Explanation: Starting with nums = [3,1,3,4,3]:
- Remove the first two 3's, then nums = [1,4,3]
There are no more pairs that sum up to 6, hence a total of 1 operation.
```

`1 <= nums.length <= 10^5`

.`1 <= nums[i] <= 10^9`

.`1 <= k <= 10^9`

.

You can use a map to count the appearances of the elements of `nums`

.

For `nums = [3,1,3,4,3]`

and `k = 6`

:

Initialize

`count = 0`

.For

`i = 0`

:`m[3] = 1`

;`k - 3 = 3`

but`m[3]`

is only`1`

, not enough to have two numbers.For

`i = 1`

:`m[1] = 1`

;`k - 1 = 5`

and`m[5] = 0`

.For

`i = 2`

:`m[3] = 2`

;`k - 3 = 3`

and`m[3] = 2`

just enough to have two numbers to perform the sum.`count = 1`

. Erase those two values`3`

's from the map:`m[3] = 0`

.For

`i = 3`

:`m[4] = 1`

;`k - 4 = 2`

and`m[2] = 0`

.For

`i = 4`

:`m[3] = 1`

;`k - 3 = 3`

but`m[3]`

is only`1`

, not enough to have two numbers.Final

`count = 1`

.

```
#include <vector>
#include <iostream>
#include <unordered_map>
using namespace std;
int maxOperations(vector<int>& nums, int k) {
unordered_map<int,int> m;
int count = 0;
for (int a : nums) {
m[a]++;
if (m[k - a] > 0) {
if (a != k - a || m[a] >= 2) {
count++;
m[a]--;
m[k - a]--;
}
}
}
return count;
}
int main() {
vector<int> nums{1,2,3,4};
cout << maxOperations(nums, 5) << endl;
nums = {3,1,3,4,3};
cout << maxOperations(nums, 6) << endl;
}
```

```
Output:
2
1
```

Runtime:

`O(N)`

, where`N = nums.length`

.Extra space:

`O(N)`

.

Given `head`

, the head of a linked list, determine if the linked list has a cycle in it.

Return `true`

if there is a cycle in the linked list. Otherwise, return `false`

.

```
Input: head = [3,2,0,-4], where -4 links next to 2.
Output: true
```

```
Input: head = [1,2], where 2 links next to 1.
Output: true
```

```
Input: head = [1], and 1 links to NULL.
Output: false
Explanation: There is no cycle in this linked list.
```

The number of the nodes in the list is in the range

`[0, 10^4]`

.`-10^5 <= Node.val <= 10^5`

.

**Follow up:** Can you solve it using `O(1)`

(i.e., constant) memory?

```
#include <unordered_map>
#include <iostream>
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
bool hasCycle(ListNode *head) {
std::unordered_map<ListNode*, int> m;
while (head) {
if (m[head] > 0) {
return true;
}
m[head]++;
head = head->next;
}
return false;
}
int main() {
{
ListNode three(3);
ListNode two(2);
three.next = &two;
ListNode zero(0);
two.next = &zero;
ListNode four(4);
zero.next = &four;
four.next = &two;
std::cout << hasCycle(&three) << std::endl;
}
{
ListNode one(1);
ListNode two(2);
one.next = &two;
two.next = &one;
std::cout << hasCycle(&one) << std::endl;
}
{
ListNode one(1);
std::cout << hasCycle(&one) << std::endl;
}
}
```

```
Output:
1
1
0
```

Runtime:

`O(N)`

, where`N`

is the length of the linked list.Extra space:

`O(N)`

.

Imagine there are two runners both start to run along the linked list from the `head`

. One runs twice faster than the other.

If the linked list has a cycle in it, they will meet at some point. Otherwise, they never meet each other.

The slower runs `[3,2,0,-4,2,0,...]`

while the faster runs `[3,0,2,-4,0,2,...]`

. They meet each other at node `-4`

after three steps.

The slower runs `[1,2,1,2,...]`

while the faster runs `[1,1,1,...]`

. They meet each other at node `1`

after two steps.

```
#include <iostream>
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
bool hasCycle(ListNode *head) {
if (head == nullptr) {
return false;
}
ListNode* fast = head;
ListNode* slow = head;
while (fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
if (fast == slow) {
return true;
}
}
return false;
}
int main() {
{
ListNode three(3);
ListNode two(2);
three.next = &two;
ListNode zero(0);
two.next = &zero;
ListNode four(4);
zero.next = &four;
four.next = &two;
std::cout << hasCycle(&three) << std::endl;
}
{
ListNode one(1);
ListNode two(2);
one.next = &two;
two.next = &one;
std::cout << hasCycle(&one) << std::endl;
}
{
ListNode one(1);
std::cout << hasCycle(&one) << std::endl;
}
}
```

```
Output:
1
1
0
```

Runtime:

`O(N)`

, where`N`

is the length of the linked list.Extra space:

`O(1)`

.

Given the `root`

of a binary tree, return its maximum depth.

A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

```
Input: root = [3,9,20,null,null,15,7]
Output: 3
```

```
Input: root = [1,null,2]
Output: 2
```

The number of nodes in the tree is in the range

`[0, 10^4]`

.`-100 <= Node.val <= 100`

.

You have the following recursive relationship between the `root`

and its children.

```
maxDepth(root) = max(maxDepth(root->left), maxDepth(root->right))
```

```
#include <iostream>
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
int maxDepth(TreeNode* root) {
if (root == nullptr) {
return 0;
}
return 1 + std::max(maxDepth(root->left), maxDepth(root->right));
}
int main() {
TreeNode fifteen(15);
TreeNode seven(7);
TreeNode twenty(20, &fifteen, &seven);
TreeNode nine(9);
TreeNode three(3, &nine, &twenty);
std::cout << maxDepth(&three) << std::endl;
TreeNode two(2);
TreeNode one(1, nullptr, &two);
std::cout << maxDepth(&one) << std::endl;
}
```

```
Output:
3
2
```

Runtime:

`O(N)`

, where`N`

is the number of nodes.Extra space:

`O(N)`

.

Given an integer `n`

, return the number of strings of length `n`

that consist only of vowels (`a`

, `e`

, `i`

, `o`

, `u`

) and are lexicographically sorted.

A string `s`

is lexicographically sorted if for all valid `i`

, `s[i]`

is the same as or comes before `s[i+1]`

in the alphabet.

```
Input: n = 1
Output: 5
Explanation: The 5 sorted strings that consist of vowels only are ["a","e","i","o","u"].
```

```
Input: n = 2
Output: 15
Explanation: The 15 sorted strings that consist of vowels only are
["aa","ae","ai","ao","au","ee","ei","eo","eu","ii","io","iu","oo","ou","uu"].
Note that "ea" is not a valid string since 'e' comes after 'a' in the alphabet.
```

```
Input: n = 33
Output: 66045
```

`1 <= n <= 50`

.

Let us find the relationship of the strings between the vowels.

For `n = 3`

:

There is (always) only one string starting from

`u`

, which is`uuu`

.There are 3 strings starting from

`o`

:`ooo`

,`oou`

and`ouu`

.There are 6 strings starting from

`i`

:`iii`

,`iio`

,`iiu`

,`ioo`

,`iou`

,`iuu`

.There are 10 strings starting from

`e`

:`eee`

,`eei`

,`eeo`

,`eeu`

,`eii`

,`eio`

,`eiu`

,`eoo`

,`eou`

,`euu`

.There are 15 strings starting from

`a`

:`aaa`

,`aae`

,`aai`

,`aao`

,`aau`

,`aee`

,`aei`

,`aeo`

,`aeu`

,`aii`

,`aio`

,`aiu`

,`aoo`

,`aou`

,`auu`

.In total: there are 35 strings that satisfy the problem.

In Example 3, if you ignore the leading vowel of those strings, then the shorted strings of the line above all appear in the ones of the line below and the remaining strings of the line below come from `n = 2`

.

More precisely:

All the shorted strings

`oo`

,`ou`

and`uu`

starting from`o`

appear on the ones starting from`i`

. The remaining`ii`

,`io`

,`iu`

starting from`i`

come from the strings of length`n = 2`

(see Example 2).Similarly, all shorted strings

`ii`

,`io`

,`iu`

,`oo`

,`ou`

,`uu`

starting from`i`

appear on the ones starting from`e`

. The remaining`ee`

,`ei`

,`eo`

,`eu`

come from`n = 2`

.And so on.

That leads to the following recursive relationship.

Let `S(x, n)`

be the number of strings of length `n`

starting from a vowel `x`

. Then

`S('o', n) = S('o', n - 1) + S('u', n)`

for all`n > 1`

.`S('i', n) = S('i', n - 1) + S('o', n)`

for all`n > 1`

.`S('e', n) = S('e', n - 1) + S('i', n)`

for all`n > 1`

.`S('a', n) = S('a', n - 1) + S('e', n)`

for all`n > 1`

.`S(x, 1) = 1`

for all vowels`x`

.`S('u', n) = 1`

for all`n >= 1`

.

For this problem, you want to compute

```
S(n) = S('a', n) + S('e', n) + S('i', n) + S('o', n) + S('u', n).
```

```
#include <iostream>
using namespace std;
int countVowelStrings(int n) {
int a, e, i, o, u;
a = e = i = o = u = 1;
while (n > 1) {
o += u;
i += o;
e += i;
a += e;
n--;
}
return a + e + i + o + u;
}
int main() {
cout << countVowelStrings(1) << endl;
cout << countVowelStrings(2) << endl;
cout << countVowelStrings(33) << endl;
}
```

```
Output:
5
15
66045
```

Runtime:

`O(n)`

.Extra space:

`O(1)`

.

The strings of length `n`

you want to count are formed by a number of `'a'`

, then some number of `'e'`

, then some number of `'i'`

, then some number of `'o'`

and finally some number of `'u'`

.

So it looks like this

```
s = "aa..aee..eii..ioo..ouu..u".
```

And you want to count how many possibilities of such strings of length `n`

.

One way to count it is using combinatorics in mathematics.

If you separate the groups of vowels by `'|'`

like this

```
s = "aa..a|ee..e|ii..i|oo..o|uu..u",
```

the problem becomes counting how many ways of putting those 4 separators `'|'`

to form a string of length `n + 4`

.

In combinatorics, the solution is `(n + 4 choose 4)`

, where `(n choose k)`

is the binomial coefficient:

The final number of strings is

```
#include <iostream>
using namespace std;
int countVowelStrings(int n) {
return (n + 1) * (n + 2) * (n + 3) * (n + 4) / 24;
}
int main() {
cout << countVowelStrings(1) << endl;
cout << countVowelStrings(2) << endl;
cout << countVowelStrings(33) << endl;
}
```

```
Output:
5
15
66045
```

Runtime:

`O(1)`

.Extra space:

`O(1)`

.