Given a positive integer `n`

, generate an `n x n`

matrix filled with elements from `1`

to `n^2`

in spiral order.

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

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

`1 <= n <= 20`

.

Starting from the top left of the matrix.

Going along the spiral direction.

Put the value to the matrix, starting from

`1`

.

`#include <vector>#include <iostream>using namespace std;enum Direction {RIGHT, DOWN, LEFT, UP};vector<vector<int>> generateMatrix(int n) { vector<vector<int>> m(n, vector<int>(n)); int bottom = n - 1; int right = n - 1; int top = 0; int left = 0; int row = 0; int col = 0; Direction d = RIGHT; int a = 1; while (top <= bottom && left <= right) { m[row][col] = a++; switch (d) { case RIGHT: if (col == right) { top++; d = DOWN; row++; } else { col++; } break; case DOWN: if (row == bottom) { right--; d = LEFT; col--; } else { row++; } break; case LEFT: if (col == left) { bottom--; d = UP; row--; } else { col--; } break; case UP: if (row == top) { left++; d = RIGHT; col++; } else { row--; } break; } } return m;}void printResult(vector<vector<int>>& m) { cout << "["; for (auto& r : m) { cout << "["; for (int a : r) { cout << a << ","; } cout << "]"; } cout << "]\n";}int main() { auto m = generateMatrix(3); printResult(m); m = generateMatrix(1); printResult(m);}`

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

The code creates a 2D vector

`m`

of size`n x n`

to represent the square matrix. It initializes it with all zeros.It defines variables

`bottom`

,`right`

,`top`

, and`left`

to keep track of the boundaries of the matrix. Initially, they are set to the indexes of the outermost rows and columns of the matrix.The code initializes

`row`

and`col`

to 0, representing the current position in the matrix.It creates an {index}

`enumDirection`

to represent the current direction of movement (`RIGHT`

,`DOWN`

,`LEFT`

,`UP`

). It initializes`d`

to`RIGHT`

to start moving to the right.The code initializes an integer

`a`

to 1, which will be used to fill the matrix with incrementing values.It uses a while loop to traverse the matrix and fills it with values as long as the

`top`

boundary is less than or equal to the`bottom`

boundary and the`left`

boundary is less than or equal to the`right`

boundary.Inside the loop, it fills the current position

`(row, col)`

in the matrix with the value`a`

and increment`a`

by 1.The code uses a {index}

`switch`

statement based on the current direction`d`

to determine the next move:If

`d`

is RIGHT, it checks if`col`

has reached the`right`

boundary. If it has, it moves to the next direction (`DOWN`

) and update`row`

accordingly; otherwise, increment`col`

.Similar logic is applied for the

`DOWN`

,`LEFT`

, and`UP`

directions, adjusting`row`

and`col`

accordingly and changing direction when needed.

Once the loop is complete, the matrix is filled in a spiral order, and the function returns the filled matrix.

Runtime:

`O(n^2)`

, where`n x n`

is the size of the matrix.Extra space:

`O(1)`

.

Thanks for reading! **Get my book "10 Classic Coding Challenges"** for FREE.

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: 11Explanation: The triangle looks like: 2 3 4 6 5 74 1 8 3The 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 position `(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`

This solution finds the minimum path sum from the top to the bottom of a triangle, represented as a vector of vectors. It uses dynamic programming to calculate the minimum path sum efficiently.

The algorithm initializes a `minTotal`

vector of vectors to store the minimum path sum for each element in the `triangle`

. It starts by setting the first row of `minTotal`

to be the same as the first row of the `triangle`

.

Then, it iterates through the rows of the `triangle`

starting from the second row. For each element in the current row, it calculates the minimum path sum by considering the two possible paths from the previous row that lead to that element. It takes the minimum of the two paths and adds the current element's value. This way, it accumulates the minimum path sum efficiently.

The algorithm continues this process until it reaches the last row of the `triangle`

. Finally, it returns the minimum element from the last row of `minTotal`

, which represents the minimum path sum from top to bottom.

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`

In this solution, vector `minTotal`

stores only the minimum path sums for each row of the triangle. It starts by setting the first element of `minTotal`

to the value of the top element of the triangle.

Runtime:

`O(n*n/2)`

, where`n = triangle.length`

.Extra space:

`O(n)`

.

Thanks for reading! Get my book "10 Classic Coding Challenges" for FREE.

]]>Given a string `s`

, find the length of the longest substring without repeating characters.

`Input: s = "abcabcbb"Output: 3Explanation: The answer is "abc", with a length of 3.`

`Input: s = "bbbbb"Output: 1Explanation: The answer is "b", with the length of 1.`

`Input: s = "pwwkew"Output: 3Explanation: The answer is "wke", with a length of 3.Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.`

`0 <= s.length <= 5 * 10^4`

.`s`

consists of English letters, digits, symbols and spaces.

One way of checking the repetition of the characters is by using a map to store their indices. For example:

`last_visit[s[i]] = i`

You might want to find every substring of nonrepeating characters in the string `s`

, then identify the longest one among them.

The character you are checking its repetition and computing the length should be done within its substring;

The map should always update the latest visited index of a character; and

The starting index of a substring is also updated when repetition happens.

For the string `s = "abcabcbb"`

:

When you visit the second letter

`'a'`

, the first substring is formed`"abc"`

, the next substring starts from the second letter`'a'`

:`start = 3`

,`last_visit['a']`

is updated to be`3`

.When you visit the second letter

`'b'`

, its`last_visit['b']`

is updated to be`4`

.Repetition is found when you visit the third letter

`'b'`

, the second substring`"abc"`

is formed. The next`start = 6`

;`last_visit['b'] = 6`

.The fourth letter

`'b'`

causes a repetition and forms a one-letter substring`"b"`

.The string

`s`

ends and form another one-letter substring`"b"`

.

`#include <iostream>#include <unordered_map>#include <algorithm>using namespace std;int lengthOfLongestSubstring(string s) { unordered_map<char, int> last_visit; int maxLen = 0; int start = -1; for (int i = 0; i < s.length(); i++) { auto it = last_visit.find(s.at(i)); if (it != last_visit.end()) { start = max(start, it->second); it->second = i; } else { last_visit.insert({s.at(i), i}); } maxLen = max(maxLen, i - start); } return maxLen;}int main() { cout << lengthOfLongestSubstring("abcabcbb") << endl; cout << lengthOfLongestSubstring("bbbbb") << endl; cout << lengthOfLongestSubstring("pwwkew") << endl;}`

`Output:313`

Runtime:

`O(N)`

, where`N = s.length`

.Extra space:

`O(N)`

.

You can initialize the

`start`

index of the substrings with`-1`

to deal with the boundary cases.As a best practice, when you check if a map contains a key and retrieve its value, use an iterator and

`find()`

like the above solution. DO NOT implement as follow

`if (last_visit.find(s.at(i)) != last_visit.end()) { start = max(start, last_visit[s.at(i)]);}`

Because the operator `[]`

might perform an additional `find()`

.

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

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: 17Explanation: The optimal subarray here is [2,4,5,6].`

`Input: nums = [5,2,1,2,5,2,1,2,5]Output: 8Explanation: 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:178`

This C++ code defines a function `maximumUniqueSubarray`

that finds the maximum sum of a subarray in the given vector `nums`

with the constraint that all elements must be unique. It uses two key techniques: prefix sums and a sliding window approach.

Runtime:

`O(N)`

, where`N = nums.length`

.Extra space:

`O(N)`

.

Thanks for reading. Get my book "10 Classic Coding Challenges" for FREE.

]]>While coding interviews can be challenging, even for experienced candidates, avoiding common mistakes is crucial to success. This comprehensive guide will explore the **most common mistakes** in coding interviews and provide strategies to avoid them, helping you excel in your next technical interview.

Coding interviews assess candidates' **technical skills**, **problem-solving ability**, and **coding proficiency**. Companies use them to determine if a candidate can handle the job demands.

For the interviewee, performing well in these interviews is often a gateway to exciting job opportunities and career advancement. However, making mistakes during coding interviews can be a significant obstacle. Let's dive into some of the most common pitfalls and how to avoid them.

**Mistake:** A lack of preparation is one of the most common and detrimental mistakes. Some candidates underestimate the importance of thorough preparation, assuming their experience or knowledge is sufficient to carry them through the interview.

**Avoidance:** To prepare effectively, review the fundamentals of **data structures**, **algorithms**, and **problem-solving techniques**. Invest time practicing coding challenges on platforms like LeetCode, HackerRank, or CodeSignal. Consider conducting **mock interviews** with peers or mentors to simulate the interview experience.

**Mistake:** Time management can be a significant challenge in coding interviews. Candidates may spend **too much time on a single problem**, leaving insufficient time for other questions.

**Avoidance:** Practice time management by setting time limits when solving practice problems. In real interviews, it's essential to maintain a steady pace. If you are stuck on a particular problem, consider moving on to other questions and returning to the challenging one later. **Prioritize questions based on your strengths and tackle the low-hanging fruit first**.

**Mistake:** Some candidates remain **silent** during interviews, failing to communicate their thoughts to the interviewer. This can lead to **misunderstandings** and missed opportunities to showcase their problem-solving skills.

**Avoidance:** Communicate your thought process. Explain your approach before starting to code. Discuss your **assumptions** and **strategies** with the interviewer. Effective communication demonstrates your problem-solving abilities and allows you to receive valuable **feedback**. Please **don't assume** the interviewer can read your mind; they appreciate clear, structured communication.

**Mistake:** Neglecting edge cases or failing to consider all possible scenarios can lead to **incomplete** or **incorrect** solutions.

**Avoidance:** Always consider edge cases and test your code against them. Discuss **potential edge cases** with the interviewer to demonstrate your thorough problem-solving approach. Address **boundary conditions** and exceptional scenarios explicitly in your code.

**Mistake:** Some candidates tend to overcomplicate their solutions. This can lead to more **complex** and **error-prone** code, which is challenging for the interviewer to understand.

**Avoidance:** Strive for **simplicity** in your solutions. Break the problem down into **smaller**, **manageable** steps. Write code that is **clean**, **easy** to understand, and **efficient**. Remember that the goal is to find a **working** solution, not necessarily the most elegant one. **Prioritize clarity over complexity**.

**Mistake:** Candidates may become overly concerned with **perfect syntax** during interviews, leading to slow progress and stress.

**Avoidance:** While correct syntax is essential, prioritize problem-solving and algorithmic thinking. If you make a minor syntax error, the interviewer will often overlook it if your approach is sound. Concentrate on conveying your understanding of the problem and how you intend to solve it. Focus on your **problem-solving** abilities rather than syntax perfection.

**Mistake:** Some candidates **give up too quickly** when encountering difficulties in a problem. This can prevent them from reaching a solution and showcasing their problem-solving skills.

**Avoidance:** Persistence is key. **Don't give up at the first sign of difficulty**. Approach the problem methodically, break it into smaller subproblems, and tackle each. If you get stuck, **communicate** your thought process and discuss potential approaches with the interviewer. Interviewers often appreciate your determination and problem-solving resilience.

**Mistake:** Candidates often **make assumptions** about the problem without seeking clarification from the interviewer. This can lead to misunderstandings and incorrect solutions.

**Avoidance:** Ask questions to **clarify** any ambiguities or uncertainties in the problem statement. Don't hesitate to seek **additional information** or constraints to guide your solution. Interviewers appreciate candidates who ask thoughtful questions and validate their understanding of the problem.

**Mistake:** Failing to test your solution thoroughly can result in **uncaught bugs** or errors.

**Avoidance:** After writing your code, **test** it with various inputs, including common and edge cases. Verify that your solution produces the expected output and handles all possible scenarios. Demonstrating the effectiveness of your code through testing can enhance your credibility and reassure the interviewer that your solution is robust.

**Mistake:** Rejections in coding interviews can be disheartening, but not learning from them can hinder your progress.

**Avoidance:** Treat rejections as opportunities to **learn** and **improve**. **Request feedback** from interviewers or mentors to understand your weaknesses and areas for growth. Adjust your preparation based on the feedback received to increase your chances of success in future interviews. Continuous improvement is essential in the competitive field of software engineering.

**Mistake:** Some candidates feel they must solve problems independently, leading to frustration and **wasted time**.

**Avoidance:** Don't hesitate to seek help or hints from the interviewer if you're stuck. They may provide valuable guidance or nudges to help you find the correct solution. It's better to **seek help** than to remain stuck and fail to solve the problem. Interviewers are often interested in your problem-solving approach and how you adapt to new information.

**Mistake:** Failing to tailor your interview preparation to the **specific** company or role can result in suboptimal performance.

**Avoidance:** **Research** the company's interview process and expectations. **Understand** the technologies and languages they use. Tailor your preparation to **align with** the company's requirements and industry trends. If a company strongly focuses on a particular programming language, ensure your skills in that language are up to par.

Mastering coding interviews is valuable for any aspiring software engineer or developer. Avoiding common mistakes and following best practices can significantly increase your chances of success. Remember to **focus on problem-solving**, **communicate effectively**, and **continuously improve your skills**. With dedication and a structured approach to interview preparation, you can excel in coding interviews and secure the job you desire.

Coding interviews are not just about technical knowledge; they also showcase your problem-solving, communication, and adaptability skills. You'll perform better in interviews and grow as a well-rounded software professional by learning from mistakes and consistently improving.

]]>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 = 16Output: true`

`Input: n = 5Output: false`

`Input: n = 1Output: 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:101`

Runtime:

`O(logn)`

.Extra space:

`O(1)`

.

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

`1 : 14 : 10016 : 1000064 : 1000000256 : 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:101`

Runtime:

`O(1)`

.Extra space:

`O(1)`

.

Thanks for reading. Get my book "10 Classic Coding Challenges" for FREE:

]]>The problem involves the International Morse Code, which defines a standard way to encode letters with dots and dashes. Each English letter corresponds to a specific sequence in Morse Code, and a full table mapping each letter is provided.

For instance, `'a'`

is encoded as `".-"`

, `'b'`

as `"-..."`

, and so on.

The full table for the `26`

letters of the English alphabet is given below:

`[".-", "-...", "-.-.", "-..", ".", "..-.", "--.","....", "..", ".---", "-.-", ".-..", "--", "-.","---", ".--.", "--.-", ".-.", "...", "-", "..-","...-", ".--", "-..-", "-.--", "--.."]`

You are given an array of strings named `words`

, where each word can be represented as a concatenation of the Morse code for each of its letters. For example, the word `"cab"`

can be represented as `"-.-..--..."`

, which is the concatenation of `"-.-."`

, `".-"`

, and `"-..."`

. This concatenated Morse code representation is referred to as the "transformation" of a word.

Your task is to count the number of different transformations that can be obtained from all the words in the given array.

`Input: words = ["gin","zen","gig","msg"]Output: 2Explanation: The transformation of each word is:"gin" -> "--...-.""zen" -> "--...-.""gig" -> "--...--.""msg" -> "--...--."There are 2 different transformations: "--...-." and "--...--.".`

`Input: words = ["a"]Output: 1`

`1 <= words.length <= 100`

.`1 <= words[i].length <= 12`

.`words[i]`

consists of lowercase English letters.

`#include <iostream>#include <vector>#include <unordered_set>using namespace std;int uniqueMorseRepresentations(vector<string>& words) { vector<string> morse{ ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.." }; unordered_set<string> transformations; for (string& w : words) { string s{""}; for (char& c : w) { s += morse[c - 'a']; } transformations.insert(s); } return transformations.size();}int main() { vector<string> words{"gin","zen","gig","msg"}; cout << uniqueMorseRepresentations(words) << endl; words = {"a"}; cout << uniqueMorseRepresentations(words) << endl;}`

`Output:21`

The solution begins with a predefined mapping of lowercase English letters to their corresponding Morse code representations. The Morse code representations are stored in a vector called

`morse`

.An

`unordered_set<string> transformations`

is used to store the unique Morse code representations generated from the input words. This set will automatically ensure that only unique representations are stored.The code iterates through each word in the

`words`

vector. For each word, it initializes an empty string`s`

to store the Morse code representation of that word.It then iterates through each character in the word. For each character

`c`

in the word, it appends the corresponding Morse code representation (retrieved from the`morse`

vector) for that character to the`s`

string. The mapping is accessed using`morse[c - 'a']`

.After constructing the Morse code representation for the current word, it inserts the

`s`

string into the`transformations`

set. If`s`

is already present in the set, it will not be added again since sets only allow unique elements.After processing all the words, the size of the

`transformations`

set is returned as the result. The size of the set corresponds to the number of unique Morse code representations generated from the input words.

This solution converts each word into Morse code based on a predefined mapping and uses an unordered set to keep track of unique representations. By inserting each representation into the set, it automatically filters out duplicates. The final result is the size of the set, which represents the number of unique Morse code representations among the input words.

Runtime:

`O(N*M)`

, where`N = words.length`

and`M = words[i].length`

.Extra space:

`O(N)`

.

Thanks for reading! **Get my book "10 Classic Coding Challenges"** for FREE.

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,]`

This solution efficiently adds two numbers represented as linked lists by iterating through both linked lists, digit by digit, and calculating the sum and carry. It also handles different scenarios for the lengths of the input lists and any remaining carry values.

Runtime:

`O(N)`

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

.Extra space:

`O(1)`

.

Thanks for reading! **Get my book "10 Classic Coding Challenges"** for FREE.

This comprehensive guide will walk you through a step-by-step approach to solving coding challenges. It helped me prepare for the coding interviews and land several jobs in my dev career.

The first and most crucial step in solving any coding challenge is thoroughly understanding the problem statement. To do this:

**Read Carefully**: Begin by reading the problem statement carefully. Pay attention to all the details, requirements, and constraints.**Sample Inputs and Outputs**: Review the sample inputs and outputs provided in the problem statement. This will help you understand the expected behavior of your solution.**Clarify Ambiguities**: If you encounter any ambiguities or uncertainties in the problem statement, don't hesitate to seek clarification. Contact the challenge provider or your instructor to ensure you clearly understand the problem.

Before you start writing code, it's essential to plan your approach. Consider the following strategies:

**Break It Down**: If the problem seems complex, break it down into smaller, more manageable subproblems. Solving each subproblem individually can make the overall task more achievable.**Data Structures and Algorithms**: Think about the data structures and algorithms you might use. Choose the most suitable ones based on the problem's requirements. This step is crucial for optimizing your solution.**Edge Cases**: Identify potential edge cases and corner cases for the problem. Consider how your code should handle these situations. It's often a good idea to address these cases later in your solution.

I always write down my ideas before typing code.

Before diving into coding, creating a pseudocode or an outline of the steps you plan to take is helpful. Pseudocode helps you structure your thoughts and provides a roadmap for your coding journey. While writing pseudocode:

Use plain language to describe the steps concisely.

Avoid detailed syntax; focus on the algorithm's logic.

Make sure your pseudocode captures the essential elements of your solution.

With a clear plan and pseudocode, it's time to start writing the actual code. Follow these guidelines:

**Use a Familiar Language**: Stick to a programming language you're comfortable with. You'll be more efficient and effective when working with a language you know well.**Follow Your Plan**: Translate your pseudocode or plan into actual code. Try to maintain a one-to-one correspondence between your plan and your code. This can help you stay organized and reduce the chances of making mistakes.**Clean Code**: Write clean and well-organized code. Use meaningful variable names and include comments to explain your code's purpose and any complex logic.

Testing is a critical part of the coding challenge process. Thoroughly test your code to ensure it behaves correctly under various conditions. Here's how to approach testing:

**Test with Sample Inputs**: Test your code with the sample inputs and outputs in the problem statement. This helps you verify that your code meets the basic requirements.**Edge Cases**: Test your code with edge cases, such as empty inputs, minimum and maximum possible values, or any other unusual situations. This ensures your code handles exceptional scenarios gracefully.**Debugging**: If you encounter errors or unexpected behavior during testing, use tools and techniques to identify and resolve issues. Pay attention to error messages and use print statements or debugging tools to trace the code's execution.

Once your code passes the initial tests, consider optimizing it for efficiency. Optimization involves improving the code's runtime performance and memory usage. Here are some optimization techniques:

**Algorithmic Optimization**: Revisit the algorithms and data structures you chose. Can more efficient alternatives achieve the same results with fewer resources?**Time and Space Complexity**: Analyze your code's time and space complexity. Aim to reduce these complexities by optimizing loops, reducing redundant computations, and minimizing memory usage.**Benchmarking**: Compare the performance of your code with various inputs. Benchmarking can help you identify bottlenecks and areas for improvement.

Remember that optimization should come after your code is correct. Don't sacrifice correctness for premature optimization.

Documentation is often overlooked but plays a crucial role in code quality and readability. When documenting your code:

Add comments to explain the purpose of functions, classes, and complex code segments.

Include comments for any non-trivial logic or algorithmic steps.

Write clear and concise docstrings for functions, describing their inputs, outputs, and usage.

Adequate documentation makes it easier for others to understand and maintain your code. It's also helpful for future reference when you revisit your code.

Before your coding challenge is complete, take some time to review and proofread your code. Here's what to look for:

**Errors and Bugs**: Carefully review your code for syntax errors, logical issues, or runtime exceptions.**Compliance with Requirements**: Double-check that your solution meets all the requirements in the problem description.**Code Style**: Ensure your code adheres to a consistent code style, such as using proper indentation, following naming conventions and using consistent formatting.

The final step in solving a coding challenge depends on the context:

**Technical Interviews**: If you're solving a coding challenge as part of a technical interview, be prepared to discuss your code and approach with the interviewer. Provide clear explanations of your thought process.**Programming Competitions**: You should submit your code as instructed in competitive programming or coding competitions. Make sure to follow the submission guidelines carefully.**Personal Projects or Learning**: If you're solving coding challenges for personal development or learning, consider sharing your solution with others through coding platforms or personal portfolios. Share instructions on how to run and test your code.

After completing a coding challenge, take some time to reflect on your solution:

Consider how you approached the problem. Were there any aha moments or insights during the process?

Think about how you could have solved the problem differently or more efficiently.

Identify areas where you encountered challenges or your knowledge is lacking, and use this as an opportunity to learn and grow.

The more you practice solving coding challenges, the more proficient you become. Regular practice is essential for honing your problem-solving skills and coding abilities. Consider these tips for effective practice:

**Variety of Challenges**: Work on various coding challenges, including those related to data structures, algorithms, and specific domains (e.g., dynamic programming, graph theory, string manipulation).**Online Platforms**: Participate in online coding platforms like LeetCode, HackerRank, CodeSignal, or Project Euler. These platforms offer a wide range of challenges and a supportive community.**Keep a Portfolio**: To showcase your solutions and progress, consider maintaining a coding challenge portfolio. This can be beneficial for job applications and personal development.**Competitions**: If you're interested in competitive programming, participate in coding competitions like ACM ICPC or TopCoder's Single Round Matches.

I chose Leetcode for its extensive collection of diverse and well-crafted problems.

Remember that solving coding challenges is a skill that improves with practice. Don't be discouraged by complex challenges; each is an opportunity to learn and grow.

Solving coding challenges is an essential skill for programmers, whether you're preparing for a technical interview, honing your coding abilities, or participating in programming competitions. Following a structured approach, understanding the problem, planning your solution, writing clean code, testing rigorously, optimizing when necessary, and practicing regularly can enhance your problem-solving skills and help you become a more proficient coder.

Coding challenges provide a platform for continuous learning and self-improvement. Through regular practice and thoughtful reflection on your solutions, you can tackle increasingly complex challenges and gain confidence in your coding abilities.

]]>So, embrace coding challenges as a valuable opportunity to learn, grow, and demonstrate your programming skills. Happy coding!

You're given an `m x n`

grid represented as an integer array called `grid`

. In this grid, there is a robot initially located at the top-left corner (i.e., `grid[0][0]`

). The robot's goal is to move to the bottom-right corner (i.e., `grid[m-1][n-1]`

). The robot can only move downwards or to the right at any given point.

The grid contains obstacles and empty spaces, which are marked as `1`

or `0`

respectively. The robot cannot pass through squares marked as obstacles.

Your task is determining the number of unique paths the robot can take to reach the bottom-right corner while avoiding obstacles.

It's important to note that the test cases are designed in such a way that the answer will always be less than or equal to `2 * 10^9`

.

`Input: obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]Output: 2Explanation: There is one obstacle in the middle of the 3x3 grid above.There are two ways to reach the bottom-right corner:1. Right -> Right -> Down -> Down2. Down -> Down -> Right -> Right`

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

`m == obstacleGrid.length`

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

.`1 <= m, n <= 100`

.`obstacleGrid[i][j]`

is`0`

or`1`

.

Let us find the relationship between the positions.

If there is no obstacle at the position `(row = i, col = j)`

, the number of paths `np[i][j]`

that the robot can take to reach this position is:

`np[i][j] = np[i - 1][j] + np[i][j - 1]`

As long as there is no obstacle in the first row,

`np[0][j] = 1`

. Otherwise,`np[0][k] = 0`

for all`k >= j0`

, where`(0, j0)`

is the position of the first obstacle in the first row.Similarly, as long as there is no obstacle in the first column,

`np[i][0] = 1`

. Otherwise,`np[k][0] = 0`

for all`k >= i0`

, where`(i0, 0)`

is the position of the first obstacle in the first column.

`#include <vector>#include <iostream>using namespace std;int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { const int row = obstacleGrid.size(); const int col = obstacleGrid[0].size(); vector<vector<int>> np(row, vector<int>(col, 0)); for (int i = 0; i < row && obstacleGrid[i][0] == 0; i++) { np[i][0] = 1; } for (int j = 0; j < col && obstacleGrid[0][j] == 0; j++) { np[0][j] = 1; } for (int i = 1; i < row; i++) { for (int j = 1; j < col; j++) { if (obstacleGrid[i][j] == 0) { np[i][j] = np[i - 1][j] + np[i][j - 1]; } } } return np[row - 1][col - 1]; }int main() { vector<vector<int>> obstacleGrid = {{0,0,0},{0,1,0},{0,0,0}}; cout << uniquePathsWithObstacles(obstacleGrid) << endl; obstacleGrid = {{0,1},{0,0}}; cout << uniquePathsWithObstacles(obstacleGrid) << endl;}`

`Output:21`

This solution computes the number of unique paths in an `m x n`

grid with obstacles using dynamic programming. It initializes a 2D vector `np`

of the same size as `obstacleGrid`

to store the number of unique paths for each cell.

First, it initializes the top row and left column of `np`

. If there are no obstacles in the top row or left column of `obstacleGrid`

, it sets the corresponding cells in `np`

to 1 because there's only one way to reach any cell in the top row or left column.

Then, it iterates through the grid starting from the second row and second column (i.e., indices (1, 1)). For each cell, if there's no obstacle (`obstacleGrid[i][j] == 0`

), it updates the value in `np`

by summing up the values from the cell directly above it and the cell to the left of it. This step efficiently accumulates the number of unique paths while avoiding obstacles.

Finally, the value at `np[row-1][col-1]`

contains the total number of unique paths to reach the bottom-right corner of the grid, which is returned as the result.

The time complexity of this solution is `O(m*n)`

, where `m`

and `n`

are the grid dimensions, as it iterates through all grid cells once to compute the unique paths efficiently. Dynamic programming avoids redundant calculations and makes this solution efficient even for large grids.

Runtime:

`O(m*n)`

.Extra space:

`O(m*n)`

.

Thanks for reading! **Get my book "10 Classic Coding Challenges"** for FREE.

You have a string called `s`

. Your objective is to locate the index of the first character in the string that does not repeat anywhere else in the string. If such a character doesn't exist, return `-1`

.

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

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

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

`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:02-1`

The code initializes an unordered map

`count`

where characters from the string are keys, and their corresponding counts (how many times they appear in the string) are values.The loop then iterates through the characters of the string

`s`

. For each character`c`

encountered, it increments its count in the`count`

map.After counting all the characters in the string, it performs a second loop, this time using an index variable

`i`

that starts from 0 and goes up to the length of the string`s`

.In this loop, it checks whether the count of the character at the current index

`i`

is equal to 1. If it is, this means that the character is unique in the string, and the function returns`i`

, which is the index of the first occurrence of that unique character.If no unique character is found during the loop, the function returns -1 to indicate that there are no unique characters in the string.

This solution has a time complexity of `O(n)`

, where `n`

is the length of the string `s`

, because it iterates through the string twice: once to count the characters and once to find the first unique character.

It also has a space complexity of `O`

`(k)`

, where `k`

is the number of distinct characters in the string, as it stores character counts in the `count`

unordered map. As the problem considers only lowercase English letters, `k = 26`

, you can give it `O(1)`

complexity.

Runtime:

`O(n)`

, where`n = s.length`

.Extra space:

`O(k)`

, where`k`

is the number of distinct characters in the string. If`k=26`

, it is`O(1)`

.

From the constraints "`s`

consists of only lowercase English letters", you can use an array of 26 elements to store the counts.

`#include <iostream>#include <vector>using namespace std;int firstUniqChar(string s) { // initializes an array of 26 elements, all set to zero std::array<int, 26> count{}; 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:02-1`

Extra space:

`O(1)`

as the array's length is fixed 26.

Thanks for reading! **Get my book "10 Classic Coding Challenges"** for FREE.

Roman numerals are represented by seven symbols: `I`

, `V`

, `X`

, `L`

, `C`

, `D`

, and `M`

.

`Symbol ValueI 1V 5X 10L 50C 100D 500M 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: 3Explanation: III = 3.`

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

`Input: s = "MCMXCIV"Output: 1994Explanation: 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:3581994`

This solution efficiently converts a Roman numeral string into an integer by iterating through the string from right to left and applying the rules of Roman numerals, where subtractive combinations are subtracted and additive combinations are added to calculate the total value. The unordered map is used to look up the values of Roman numerals.

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. Check out my* *book 10 Classic Coding Challenges*** for FREE***.*

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:10`

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:10`

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:10`

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! **Get my book "10 Classic Coding Challenges"** for FREE.

Given an integer array `nums`

of unique elements, return all possible subsets (the power set).

The solution set must not contain duplicate subsets. Return the solution in any order.

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

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

`1 <= nums.length <= 10`

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

.All the numbers of

`nums`

are unique..

You might need to find the relationship between the result of the array `nums`

with the result of itself without the last element.

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

You can see the powerset of Example 3 was obtained from the one in Example 2 with additional subsets `[2]`

, `[1,2]`

. These new subsets were constructed from subsets `[]`

, `[1]`

of Example 2 appended with the new element `2`

.

Similarly, the powerset of Example 1 was obtained from the one in Example 3 with the additional subsets `[3]`

, `[1,3]`

, `[2,3]`

, `[1,2,3]`

. These new subsets were constructed from the ones of Example 3 appended with the new element `3`

.

`#include <vector>#include <iostream>using namespace std;vector<vector<int>> subsets(vector<int>& nums) { vector<vector<int>> powerset = {{}}; int i = 0; while (i < nums.size()) { vector<vector<int>> newSubsets; for (auto subset : powerset) { subset.push_back(nums[i]); newSubsets.push_back(subset); } powerset.insert(powerset.end(), newSubsets.begin(), newSubsets.end()); i++; } return powerset;}void print(vector<vector<int>>& powerset) { for (auto& set : powerset ) { cout << "["; for (auto& element : set) { cout << element << ","; } cout << "]"; } cout << endl;}int main() { vector<int> nums{1,2,3}; auto powerset = subsets(nums); print(powerset); nums = {1}; powerset = subsets(nums); print(powerset);}`

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

The code initializes an empty vector of vectors called

`powerset`

to store the subsets. It starts with an initial subset containing an empty vector, representing the empty set:`{{}}`

.Within the loop, it creates a new vector of vectors called

`newSubsets`

to store subsets that include the`i`

-th element of`nums`

.It iterates through the existing subsets in

`powerset`

. For each subset, it creates a copy of it (represented by the`subset`

variable), adds the`i`

-th element from`nums`

to the copied subset, and pushes the modified subset into the`newSubsets`

vector.After processing all existing subsets, the code adds the contents of

`newSubsets`

to the`powerset`

vector. This effectively combines the current subsets with subsets that include the`i`

-th element of`nums`

.It repeats steps 2-4 until all elements in

`nums`

have been considered.Finally, the code returns the

`powerset`

, which now contains all possible subsets of`nums`

.

This code essentially generates subsets by iteratively adding each element of `nums`

to the existing subsets and accumulating the results. The time complexity of this code is `O(2^N)`

, where `N`

is the number of elements in `nums`

, as it generates all possible subsets. The space complexity is also `O(2^N)`

due to the space required to store the subsets.

Runtime:

`O(2^N)`

.Extra space:

`O(2^N)`

.

*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`

already sorted in non-decreasing order, you must remove duplicates so that each unique element appears at most twice. The relative order of the elements should remain unchanged.

Since changing the array's length in some programming languages is impossible, you must place the result in the first part of the `nums`

array. In other words, if there are `k`

elements after removing the duplicates, the first `k`

elements of `nums`

should contain the final result. Anything beyond the first `k`

elements is not important.

You should return the value of `k`

after placing the final result in the first `k`

slots of the `nums`

array.

The key requirement is to accomplish this task without using extra space for another array. It must be done by modifying the input array `nums`

in-place, using only `O(1)`

extra memory.

`Input: nums = [1,1,1,2,2,3]Output: 5, nums = [1,1,2,2,3,_]Explanation: Your function should return k = 5, with the first five elements of nums being 1, 1, 2, 2, and 3, respectively.What you leave does not matter beyond the returned k (hence, they are underscores).`

`Input: nums = [0,0,1,1,1,1,2,3,3]Output: 7, nums = [0,0,1,1,2,3,3,_,_]Explanation: Your function should return k = 7, with the first seven elements of nums being 0, 0, 1, 1, 2, 3, and 3, respectively.What you leave does not matter beyond the returned k (hence, they are underscores).`

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

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

.`nums`

is sorted in**non-decreasing**order.

In order for each unique element to appear **at most twice**, you have to erase the further appearances if they exist.

Since the array `nums`

is sorted, you can determine that existence by checking if `nums[i] == nums[i-2]`

for `2 <= i < nums.length`

.

`#include <vector>#include <iostream>using namespace std;int removeDuplicates(vector<int>& nums) { int i = 2; while (i < nums.size()) { if (nums[i] == nums[i-2]) { int j = i; while (j < nums.size() && nums[j] == nums[i]) { j++; } nums.erase(nums.begin() + i, nums.begin() + j); } else { i++; } } return nums.size();}void printResult(const int k, const vector<int>& nums) { cout << k << ", ["; for (int i = 0; i < k ; i++) { cout << nums[i] << ","; } cout << "]\n";}int main() { vector<int> nums{1,1,1,2,2,3}; printResult(removeDuplicates(nums), nums); nums = {0,0,1,1,1,1,2,3,3}; printResult(removeDuplicates(nums), nums);}`

`Output:5, [1,1,2,2,3,]7, [0,0,1,1,2,3,3,]`

Inside the loop, it checks if the element at index

`i`

is equal to the element two positions before it.If the condition is met, there are more than two occurrences of the current element. We need to remove the excess duplicates while preserving two instances. To do this, a second while loop is used until the duplicate elements are no longer found. At this point,

`j`

will be the index of the first element that differs from the current element.After finding the range of duplicate elements to remove (from index

`i`

to`j-1`

, inclusive), it uses the`vector`

's`erase`

function to remove these elements from the`nums`

array. This effectively keeps only two instances of the current element.If the condition in step 2 is not met (i.e., there are at most two occurrences of the current element), it moves the index

`i`

to the next unique element in the array.Repeat steps 2 to 4 until

`i`

has traversed the entire array. The while loop removes all duplicate elements beyond two occurrences while maintaining the order of unique elements.Once the loop finishes, the

`nums`

array contains unique elements with at most two occurrences of each. Return the size of the modified array using`nums.size()`

.

This solution efficiently removes duplicates from the sorted array by checking for duplicates and erasing the excess occurrences while preserving two instances of each unique element. It then returns the length of the modified array.

Runtime:

- Worst case:
`O(N^2/3)`

, where`N = nums.size()`

. The complexity of the`erase()`

method is linear in`N`

. The worst case is when`erase()`

is called maximum`N/3`

times.

- Worst case:

` Example of the worst case: nums = [1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6].`

- On average:
`O(N)`

since the number of`erase()`

calls is`O(1)`

.

- Extra space:
`O(1)`

.

You might need to avoid the `erase()`

method in the solution above to reduce the complexity. Moreover, after removing the duplicates, the problem only cares about the first `k`

elements of the array `nums`

.

If you look at the final result after removing duplication, the **expected** `nums`

satisfies

`nums[i] > nums[i-2] for 2 <= i < nums.length.`

You can use this invariant to **reassign** the array `nums`

only the satisfied elements.

`#include <vector>#include <iostream>using namespace std;int removeDuplicates(vector<int>& nums) { if (nums.size() <= 2) { return nums.size(); } int k = 2; int i = 2; while (i < nums.size()) { if (nums[i] > nums[k - 2]) { nums[k++] = nums[i]; } i++; } return k;}void printResult(const int k, const vector<int>& nums) { cout << k << ", ["; for (int i = 0; i < k ; i++) { cout << nums[i] << ","; } cout << "]\n";}int main() { vector<int> nums{1,1,1,2,2,3}; printResult(removeDuplicates(nums), nums); nums = {0,0,1,1,1,1,2,3,3}; printResult(removeDuplicates(nums), nums);}`

`Output:Output:5, [1,1,2,2,3,]7, [0,0,1,1,2,3,3,]`

The code checks the size of the input array

`nums`

. If it has 2 or fewer elements, there's no need to perform any removals, so the function simply returns the size of the original array.It initializes two variables:

`k`

: This will represent the length of the resulting array after removing duplicates (initially set to 2 since we allow up to two occurrences of each element).`i`

: This is an iterator that starts from the array's third element (index 2) and is used to traverse the array.

It starts a loop that iterates from the third element (

`i = 2`

) to the end of the array.Inside the loop, it compares the current element at index

`i`

with the element at`k - 2`

. This comparison checks if the current element exceeds the previous two positions. If it is, this means it's a new element. Otherwise, it is a third occurrence of the same element, which we want to skip.If the current element is greater than the element at index

`k - 2`

, it updates the element at index`k`

with the current element. Then, it increments`k`

to indicate that a new unique element has been found.Continue iterating through the array by incrementing

`i`

.Once the loop finishes, the array up to index

`k - 1`

contains the unique elements with at most two occurrences each, and the rest of the array can be ignored.Finally, return the value of

`k`

, which represents the length of the resulting array.

This solution effectively modifies the input array in-place, removing duplicates that occur more than twice while maintaining the desired order of unique elements. It does so in a single pass through the array, resulting in a time complexity of `O(N)`

, where `N`

is the number of elements in the array.

Runtime:

`O(N)`

, where`N = nums.size()`

.Extra space:

`O(1)`

.

*Thanks for reading. Check out my book* *10 Classic Coding Challenges**for free* *here**.*

Given the starting nodes of two sorted linked lists, `list1`

and `list2`

, your task is to combine these lists into a single sorted linked list.

This merged list should be created by connecting the nodes from both `list1`

and `list2`

. Finally, you should return the starting node of the resulting merged linked list.

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

`Input: list1 = [], list2 = []Output: []`

`Input: list1 = [], list2 = [0]Output: [0]`

The number of nodes in both lists is in the range

`[0, 50]`

.`-100 <= Node.val <= 100`

.Both

`list1`

and`list2`

are sorted in non-decreasing order.

For each pair of nodes between the two lists, pick the node having a smaller value to append to the new list.

`#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* mergeTwoLists(ListNode* list1, ListNode* list2) { if (list1 == nullptr) { return list2; } else if (list2 == nullptr) { return list1; } // identify which list is head ListNode* head = list1; if (list2->val < head->val) { head = list2; list2 = list2->next; } else { list1 = list1->next; } ListNode* node = head; while (list1 && list2) { if (list1->val < list2->val) { node->next = list1; list1 = list1->next; } else { node->next = list2; list2 = list2->next; } node = node->next; } if (list1 == nullptr) { node->next = list2; } else { node->next = list1; } return head;}void printResult(ListNode* head) { std::cout << "["; while (head) { std::cout << head->val << ","; head = head->next; } std::cout << "]\n";}int main() { ListNode four1(4); ListNode two1(2, &four1); ListNode one1(1, &two1); ListNode four2(4); ListNode three2(3, &four2); ListNode one2(1, &three2); auto newOne = mergeTwoLists(&one1, &one2); printResult(newOne); auto empty = mergeTwoLists(nullptr, nullptr); printResult(empty); ListNode zero(0); auto z = mergeTwoLists(nullptr, &zero); printResult(z);}`

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

The function begins with two base cases to handle situations where one of the input lists is empty:

If

`list1`

is empty (i.e.,`list1`

is`nullptr`

), the function simply returns`list2`

. There is no need to merge anything because`list1`

is empty.Similarly, if

`list2`

is empty (i.e.,`list2`

is`nullptr`

), the function returns`list1`

.

A

`head`

pointer will be used to keep track of the merged list. The code determines which of`list1`

and`list2`

should be the head of the merged list. It does this by comparing the values of the first nodes in`list1`

and`list2`

:If the value of the first node in

`list2`

is less than the value of the first node in`list1`

, it means that`list2`

should be the new head of the merged list. The code updates the`head`

pointer to point to`list2`

, and it advances the`list2`

pointer to the next node.If the value of the first node in

`list1`

is less than or equal to the value in`list2`

,`list1`

should be the new head. The code advances the`list1`

pointer to the next node.

The main merging process is performed using a

`while`

loop that continues as long as both`list1`

and`list2`

are not empty:Inside the loop, the code compares the values of the first nodes in

`list1`

and`list2`

:If the value in

`list1`

is smaller, the code connects the current node pointed to by`node`

to the node in`list1`

, and advances`list1`

to its next node.If the value in

`list2`

is smaller or equal, the code connects the current node pointed to by`node`

to the node in`list2`

, and advances`list2`

to its next node.

After connecting a node, the

`node`

pointer is moved to the newly connected node.

After the

`while`

loop completes, one of the input lists may still have remaining elements. To ensure that all elements are included in the merged list, the code appends the remaining nodes from either`list1`

or`list2`

(whichever is not empty) to the end of the merged list.Finally, the function returns

`head`

, which points to the head of the merged sorted linked list.

Runtime:

`O(N)`

, where`N = list1.length + list2.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 array `nums`

of size `n`

, return the minimum number of moves required to make all array elements equal.

In one move, you can increment or decrement an element of the array by `1`

.

`Input: nums = [1,2,3]Output: 2Explanation:Only two moves are needed (remember each move increments or decrements one element):[1,2,3] => [2,2,3] => [2,2,2]`

`Input: nums = [1,10,2,9]Output: 16`

`n == nums.length`

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

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

.

You are asked to move all elements of an array to the same value `M`

. The problem can be reduced to identifying what `M`

is.

First, moving elements of an unsorted array and moving a sorted one are the same. So you can assume `nums`

is sorted in some order. Let us say it is sorted in ascending order.

Second, `M`

must be in between the minimum element and the maximum one. Apparently!

We will prove that `M`

will be the median of `nums`

, which is `nums[n/2]`

of the sorted `nums`

.

In other words, we will prove that if you choose `M`

a value different from `nums[n/2]`

, then the number of moves will be increased.

In fact, if you choose `M = nums[n/2] + x`

, where `x > 0`

, then:

Each element

`nums[i]`

that is less than`M`

needs more`x`

moves, while each`nums[j]`

that is greater than`M`

can reduce`x`

moves.But the number of

`nums[i]`

is bigger than the number of`nums[j]`

.So the total number of moves is bigger.

The same arguments apply for `x < 0`

.

For `nums = [0,1,2,2,10]`

. Its median is `2`

. The minimum number of moves is `2 + 1 + 0 + 0 + 8 = 11`

.

If you choose `M = 3`

(the average value, the mean), the total number of moves is `3 + 2 + 1 + 1 + 7 = 14`

.

`#include <iostream>#include <vector>#include <algorithm>using namespace std;int minMoves2(vector<int>& nums) { sort(nums.begin(), nums.end()); const int median = nums[nums.size() / 2]; int moves = 0; for (int& a: nums) { moves += abs(a - median); } return moves;}int main() { vector<int> nums{1,2,3}; cout << minMoves2(nums) << endl; nums = {1,10,2,9}; cout << minMoves2(nums) << endl;}`

`Output:216`

Runtime:

`O(nlogn)`

, where`n = nums.length`

.Extra space:

`O(1)`

.

`std::nth_element`

to compute the medianWhat you only need in Solution 1 is the median value. Computing the total number of moves in the `for`

loop does not require the array `nums`

to be fully sorted.

In this case, you can use `std::nth_element`

to reduce the runtime complexity.

`#include <iostream>#include <vector>#include <algorithm>using namespace std;int minMoves2(vector<int>& nums) { const int mid = nums.size() / 2; std::nth_element(nums.begin(), nums.begin() + mid, nums.end()); const int median = nums[mid]; int moves = 0; for (int& a: nums) { moves += abs(a - median); } return moves;}int main() { vector<int> nums{1,2,3}; cout << minMoves2(nums) << endl; nums = {1,10,2,9}; cout << minMoves2(nums) << endl;}`

`Output:216`

Runtime:

`O(n)`

, where`n = nums.length`

.Extra space:

`O(1)`

.

In the code of Solution 2, 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].`

With this property, if `mid = nums.length / 2`

, then the value of `nums[mid]`

is unchanged no matter how `nums`

is sorted or not.

*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**.*

A string `s`

is called good if there are no two different characters in `s`

that have the same frequency.

Given a string `s`

, return the minimum number of characters you need to delete to make `s`

good.

The frequency of a character in a string is the number of times it appears in the string. For example, in the string `"aab"`

, the frequency of `'a'`

is `2`

, while the frequency of `'b'`

is `1`

.

`Input: s = "aab"Output: 0Explanation: s is already good.`

`Input: s = "aaabbbcc"Output: 2Explanation: You can delete two 'b's resulting in the good string "aaabcc".Another way is to delete one 'b' and one 'c' resulting in the good string "aaabbc".`

`Input: s = "ceabaacb"Output: 2Explanation: You can delete both 'c's resulting in the good string "eabaab".Note that we only care about characters that are still in the string at the end (i.e. frequency of 0 is ignored).`

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

.`s`

contains only lowercase English letters.

Your goal is to make all the frequencies different.

One way of doing that is by sorting the frequencies and performing the deletion.

For `s = "ceaacbb"`

, the frequencies of the characters are: `freq['a'] = 2, freq['b'] = 2, freq['c'] = 2`

and `freq['e'] = 1`

. They are already in sorted order.

Let the current frequency be the first frequency

`freq['a'] = 2`

.The next frequency is

`freq['b'] = 2`

, equal to the current frequency. Delete one appearance to make the current frequency be`1`

.The next frequency is

`freq['c'] = 2`

, bigger than the current frequency. Delete two appearances to make the current frequency be`0`

.Because the current frequency is

`0`

, delete all appearances of the remaining frequencies, which is`freq['e'] = 1`

.In total, there are

`4`

deletions.

`#include <algorithm>#include <iostream>#include <vector>using namespace std;int minDeletions(string s) { vector<int> freq(26, 0); for (char& c: s) { freq[c - 'a']++; } sort(freq.begin(), freq.end(), greater<int>()); int deletion = 0; int currentFreq = freq[0]; for (int i = 1; i < freq.size() && freq[i] > 0; i++) { if (currentFreq == 0) { deletion += freq[i]; } else if (freq[i] >= currentFreq) { deletion += freq[i] - currentFreq + 1; currentFreq--; } else { currentFreq = freq[i]; } } return deletion;}int main() { cout << minDeletions("aab") << endl; cout << minDeletions("aaabbbcc") << endl; cout << minDeletions("ceabaacb") << endl;}`

`Output:022`

Runtime:

`O(N)`

, where`N = s.length`

;Extra space:

`O(1)`

since`26`

is not a big number.

*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 assigned to put some amount of boxes onto one truck. You are given a 2D array `boxTypes`

, where `boxTypes[i] = [numberOfBoxes_i, numberOfUnitsPerBox_i]`

:

`numberOfBoxes_i`

is the number of boxes of type`i`

.`numberOfUnitsPerBox_i`

is the number of units in each box of the type`i`

.

You are also given an integer `truckSize`

, which is the maximum number of boxes that can be put on the truck. You can choose any boxes to put on the truck as long as the number of boxes does not exceed `truckSize`

.

Return the maximum total number of units that can be put on the truck.

`Input: boxTypes = [[1,3],[2,2],[3,1]], truckSize = 4Output: 8Explanation: There are:- 1 box of the first type that contains 3 units.- 2 boxes of the second type that contain 2 units each.- 3 boxes of the third type that contain 1 unit each.You can take all the boxes of the first and second types, and one box of the third type.The total number of units will be = (1 * 3) + (2 * 2) + (1 * 1) = 8.`

`Input: boxTypes = [[5,10],[2,5],[4,7],[3,9]], truckSize = 10Output: 91Explanation: (5 * 10) + (3 * 9) + (2 * 7) = 91.`

`1 <= boxTypes.length <= 1000`

.`1 <= numberOfBoxes_i, numberOfUnitsPerBox_i <= 1000`

.`1 <= truckSize <= 10^6`

.

Put the boxes having more units first.

`#include <iostream>#include <vector>#include <algorithm>using namespace std;int maximumUnits(vector<vector<int>>& boxTypes, int truckSize) { // sort for the boxes based on their number of units sort(boxTypes.begin(), boxTypes.end(), [](const vector<int>& a, const vector<int>& b) { return a[1] > b[1]; }); int maxUnits = 0; int i = 0; while (truckSize > 0 && i < boxTypes.size()) { if (boxTypes[i][0] <= truckSize) { maxUnits += boxTypes[i][0] * boxTypes[i][1]; truckSize -= boxTypes[i][0]; } else { maxUnits += truckSize * boxTypes[i][1]; break; } i++; } return maxUnits;}int main() { vector<vector<int>> boxTypes{{1,3},{2,2},{3,1}}; cout << maximumUnits(boxTypes, 4) << endl; boxTypes = {{5,10},{2,5},{4,7},{3,9}}; cout << maximumUnits(boxTypes, 10) << endl;}`

`Output:891`

Runtime:

`O(NlogN)`

, where`N = boxTypes.length`

.Extra space:

`O(1)`

.

Note that two `vector`

s can be compared. That is why you can sort them.

But in this case you want to sort them based on the number of units. That is why you need to define the comparison function like the code above. Otherwise, the `sort`

algorithm will use the dictionary order to sort them by default.

*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**.*

Given an integer `n`

, return the least number of perfect square numbers that sum to `n`

.

A **perfect square** is an integer that is the square of an integer; in other words, it is the product of some integer with itself. For example, `1`

, `4`

, `9`

, and `16`

are perfect squares while `3`

and `11`

are not.

`Input: n = 9Output: 1Explanation: 9 is already a perfect square.`

`Input: n = 13Output: 2Explanation: 13 = 4 + 9.`

`Input: n = 7Output: 4Explanation: 7 = 4 + 1 + 1 + 1.`

`Input: n = 12Output: 3Explanation: 12 = 4 + 4 + 4.`

`1 <= n <= 10^4`

.

Let us call the function to be computed `numSquares(n)`

, which calculates the least number of perfect squares that sum to `n`

.

Here are the findings.

If

`n`

is already a perfect square then`numSquares(n) = 1`

.Otherwise, it could be written as

`n = 1 + (n-1)`

, or`n = 4 + (n-4)`

, or`n = 9 + (n-9)`

, etc. which means`n`

is a sum of a perfect square (`1, 4`

or`9`

, etc.) and another number`m < n`

. That leads to the problems`numSquares(m)`

of smaller values`m`

.If you have gotten the results of the smaller problems

`numSquares(n-1)`

,`numSquares(n-4)`

,`numSquares(n-9)`

, etc. then`numSquares(n) = 1 + the minimum of those results`

.

`n = 12`

is not a perfect square. It can be written as `n = 1 + 11 = 4 + 8 = 9 + 3`

.

For

`m = 11`

, it is not a perfect square and can be written as`m = 1 + 10 = 4 + 7 = 9 + 2`

.For

`m = 8`

, it is not a perfect square and can be written as`m = 1 + 7 = 4 + 4`

(matched). You get`numSquares(8) = 2`

.For

`m = 3`

, it is not a perfect square and can be written as`m = 1 + 2`

.

You can continue to compute `numSquares(m)`

for other values `m`

in this recursive process. But you can see the case of `m = 8`

was already the best solution. And `numSquares(12) = 1 + numSquares(8) = 1 + 2 = 3`

, which is the case of `n = 12 = 4 + 4 + 4`

.

To improve runtime, you can apply *dynamic programming* to cache the `numSquares(n)`

that you have computed.

`#include <iostream>#include <cmath>#include <unordered_map>using namespace std;int nsq(int n, unordered_map<int, int>& ns) { auto it = ns.find(n); if (it != ns.end()) { return it->second; } const int sq = sqrt(n); if (sq * sq == n) { ns[n] = 1; return 1; } int result = n; for (int i = 1; i <= sq; i++) { result = min(result, nsq(n - i*i, ns)); } ns[n] = result + 1; return ns[n];}int numSquares(int n) { unordered_map<int, int> ns; return nsq(n, ns);}int main() { cout << numSquares(12) << endl; cout << numSquares(13) << endl;}`

`Output:32`

Runtime:

`O(n^2)`

.Extra space:

`O(n)`

The dynamic programming solution above is good enough. But for those who are interested in Algorithmic Number Theory, there is a very interesting theorem that can solve the problem directly without recursion.

It is called Lagrange's Four-Square Theorem, which states

every natural number can be represented as the sum of four integer squares.

It was proven by Lagrange in 1770.

`n = 12 = 4 + 4 + 4 + 0`

or `12 = 1 + 1 + 1 + 9`

.

Applying to our problem, `numSquares(n)`

can only be 1, 2, 3, or 4. Not more.

It turns into the problem of

identifying when`numSquares(n)`

returns 1, 2, 3, or 4.

Here are the cases.

If

`n`

is a perfect square,`numSquares(n) = 1`

.There is another theorem, Legendre's Three-Square Theorem, which states that

`numSquares(n)`

cannot be 1, 2, or 3 if`n`

can be expressed as`n = 4^a(8*b + 7),`

where

`a, b`

are nonnegative integers. In other words,`numSquares(n) = 4`

if`n`

is of this form.

`n = 7 = 4^0(8*0 + 7)`

. It can only be written as `7 = 4 + 1 + 1 + 1`

.

`#include <iostream>#include <cmath>using namespace std;bool isSquare(int n) { int sq = sqrt(n); return sq * sq == n;}int numSquares(int n) { if (isSquare(n)) { return 1; } // Legendre's three-square theorem int m = n; while (m % 4 == 0) { m /= 4; } if (m % 8 == 7) { return 4; } const int sq = sqrt(n); for (int i = 1; i <= sq; i++) { if (isSquare(n - i*i)) { return 2; } } return 3;}int main() { cout << numSquares(12) << endl; cout << numSquares(13) << endl;}`

`Output:32`

Runtime:

`O(logn)`

.Extra space:

`O(1)`

.

Lagrange's Four-Square Theorem and Legendre's Three-Square Theorem are so powerful to solve this problem. But you can still do a little more algebra to improve further the runtime of the implementation above.

Instead of looping over `sqrt(n)`

in the final `for`

loop, we will prove that this loop over `sqrt(m)`

is enough. That will improve runtime a lot since `m`

is much less than `n`

.

Let `m`

be the reduced value of `n`

after the Legendre's `while`

loop. It satisfies

`n = 4^a * m.`

We will prove that `numSquares(n) = numSquares(m)`

.

In fact, if `m`

is written as `m = x^2 + y^2 + z^2`

, where `x, y, z`

are nonnegative integers. Then

`n = 4^a * m = (2^a)^2 * m = (2^a * x)^2 + (2^a * y)^2 + (2^a * z)^2.`

In other words, `numSquares(n) = numSquares(m)`

.

Now you can change directly the value `n`

during the Legendre's `while`

loop without affecting the final result.

`#include <iostream>#include <cmath>using namespace std;bool isSquare(int n) { int sq = sqrt(n); return sq * sq == n;}int numSquares(int n) { if (isSquare(n)) { return 1; } // Legendre's three-square theorem while (n % 4 == 0) { n /= 4; } if (n % 8 == 7) { return 4; } const int sq = sqrt(n); for (int i = 1; i <= sq; i++) { if (isSquare(n - i*i)) { return 2; } } return 3;}int main() { cout << numSquares(12) << endl; cout << numSquares(13) << endl;}`

`Output:32`

Runtime:

`O(logn)`

.Extra space:

`O(1)`

.

The title of this coding challenge (

*Perfect squares*) gives you a hint it is more about mathematics than coding technique.It is amazing from Lagrange's Four-Square Theorem there are only four possibilities for the answer to the problem. Not many people knowing it.

You can get an optimal solution to a coding problem when you know something about the mathematics behind it.

Hope you learn something from this code challenge.

*Have fun with coding and mathematics!*

*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.*

You are given an `n x n`

2D `matrix`

representing an image. Rotate the image by 90 degrees (clockwise).

You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.

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

`Input: matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]Output: [[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]`

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

.`1 <= n <= 20`

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

.

For any square matrix, the rotation 90 degrees clockwise can be performed in two steps:

Transpose the matrix.

Mirror the matrix vertically.

`#include <iostream>#include <vector>using namespace std;void rotate(vector<vector<int>>& matrix) { const int n = matrix.size(); // transpose for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { swap(matrix[i][j], matrix[j][i]); } } // vertical mirror for (int i = 0; i < n; i++) { for (int j = 0; j < n / 2; j++ ) { swap(matrix[i][j], matrix[i][n - 1 - j]); } }}void printMatrix(vector<vector<int>>& matrix) { cout << "["; for (auto& row: matrix) { cout << "["; for (auto& a: row) { cout << a << ","; } cout << "],"; } cout << "]\n";}int main() { vector<vector<int>> matrix{{1,2,3},{4,5,6},{7,8,9}}; rotate(matrix); printMatrix(matrix); matrix = {{5,1,9,11},{2,4,8,10},{13,3,6,7},{15,14,12,16}}; rotate(matrix); printMatrix(matrix);}`

`Output:[[7,4,1,],[8,5,2,],[9,6,3,],][[15,13,2,5,],[14,3,4,1,],[12,6,8,9,],[16,7,10,11,],]`

Runtime:

`O(n^2)`

, where`n = matrix.length`

.Extra space:

`O(1)`

.

The function

`std::swap`

can be used to exchange two values.When doing the transpose or mirroring, you could visit over one-half of the matrix.

*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.*

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: 4Explanation: 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:4123`

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: 0Explanation: Ignoring leading zeroes, both "01" and "001" represent the same integer "1".`

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

`Input: version1 = "0.1", version2 = "1.1"Output: -1Explanation: 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:00-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: 2Explanation: 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:21`

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:21`

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 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.*

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) = 1F(n) = F(n - 1) + F(n - 2), for n > 1.`

Given `n`

, calculate `F(n)`

.

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

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

`Input: n = 4Output: 3Explanation: 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:123`

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:123`

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:123`

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]ExplanationMyHashSet myHashSet = new MyHashSet();myHashSet.add(1); // set = [1]myHashSet.add(2); // set = [1, 2]myHashSet.contains(1); // return TruemyHashSet.contains(3); // return False, (not found)myHashSet.add(2); // set = [1, 2]myHashSet.contains(2); // return TruemyHashSet.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:1010`

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:1010`

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]ExplanationMyCalendar myCalendar = new MyCalendar();myCalendar.book(10, 20); // return TruemyCalendar.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:101`

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:101`

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: falseExplanation: 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: trueExplanation: 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:01`

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: trueExplanation: Both s and t become "ac".`

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

`Input: s = "a#c", t = "b"Output: falseExplanation: 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:110`

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 = 2Output: 2`

`Input: nums = [1,2,3], k = 3Output: 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:223`

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:223`

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:223`

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: 1Explanation: 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:11`

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: 30Explanation:"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: 27Explanation:"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:3027`

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]ExplanationKthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);kthLargest.add(3); // return 4kthLargest.add(5); // return 5kthLargest.add(10); // return 5kthLargest.add(9); // return 8kthLargest.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:45588`

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:45588`

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 = 6Output: [1,2,3,4,5]`

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

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

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: 2Explanation: "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:232`

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:232`

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 = 1Output: [[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 = 4Output: [[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 = 9Output: [[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:2103`

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:2103`

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: 5Explanation: 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:500`

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:500`

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 = 2Output: "abcd"Explanation: There is nothing to delete.`

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

`Input: s = "pbbcggttciiippooaais", k = 2Output: "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;}`

`abcdaaps`

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:1011`

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 = 27Output: trueExplanation: 27 = 3^3.`

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

`Input: n = -1Output: falseExplanation: 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:100`

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:100`

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 sortedvector<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: 6Explanation: 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: 7Explanation: 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:672`

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:0010`

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:23`

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:23`

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:23`

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 -> 1B -> 2C -> 3...Z -> 26AA -> 27AB -> 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:128701`

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 = 1Output: 1Explanation: "1" in binary corresponds to the decimal value 1.`

`Input: n = 3Output: 27Explanation: 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 = 12Output: 505379714Explanation: 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 + 3Dec("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 + 2Dec("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:127505379714`

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**.*