Recruiters are looking for the direct outcome of a project and the impact it has on the customer or the company.

They want to see the value you bring to the table. Simply stating your work responsibilities gives the recruiter no context whether you achieved your goals.

You should focus on the impact over the outcomes.

If you have **data** to support your stated impact, you should include those. Demonstrating the monetary or performance impact you had on a project would attract the recruiter.

You can use the following template to create meaningful impact statements.

<action verb> <noun> from <data> in order to/which led to <impact>

You might not always have an "*in order to*" or "*which led to*" statement, and that's perfectly fine as long as you include a bit of data to illustrate your impact.

Let's see a few examples.

Instead of "*added keyboard navigation controls*," you should state, "*implemented keyboard navigation controls to comply with W3C accessibility standards.*"

This statement allows the recruiter to see the specific influence you had on the success of the product.

Instead of "*improved SEO algorithm*," you can state, "*increased the accuracy of search index results by 20%*."

And instead of "*conducted a training session*," you should state, "*conducted a GIT training session for 50 developers*."

Be as specific as possible and use data where appropriate.

*Thanks for reading. Check out* *my latest resume* *to see how I stated my impact on my work.*

In these sentences, the candidate would provide a quick introduction to themselves and what type of job qualifications they had.

But should you include this section or is this outdated?

A **summary** section can provide a **quick overview of your skill set and qualifications**, allowing recruiters to easily know whether you'll be a match for a role. So a well-written summary can potentially help you get noticed by a recruiter.

A summary section can be useful if you have skills that are worth highlighting at the top of your resume.

An **objective** section in contrast is a statement of your career goal - **What type of role you are looking to obtain**.

An objective section can be useful if you have limited work experience, so if you've just graduated college, this can be a useful section to include.

Your **objective** might read, "*Motivated software engineer looking to grow Java knowledge by developing an enterprise-level application*."

However, if you're a seasoned software engineer with 10 years of experience programming in Java, your **summary** statement might read, "*Experienced Java developer with 10 years architecting and building large-scale enterprise applications.*"

An objective statement denotes what you wish to achieve while a summary will showcase your accomplishments or skills.

You don't need to include an objective or summary to catch a recruiter's eye, but these sections can benefit you when you have sought-after skills to demonstrate or if you lack work experience.

I don't state a specific summary or objective on my resume. Depending on the job I might apply for, I will adjust it to include a short summary.

]]>When building a resume, content is key. The design and layout of your resume are important, but recruiters are primarily looking at your resume content. Understanding which words to use and how to phrase them effectively will go a long way toward landing you a job interview.

Some tips for writing effective resume content include:

**1. Be specific.** What specific actions did you take, and what positive outcomes did you achieve? Instead of saying "*Proficient in Microsoft Office*," specify *"Proficient in Excel, PowerPoint, and Word, with experience creating detailed spreadsheets and presentations*."

**2. Use action words.** Use words that show you took action to achieve a positive result. Recruiters want to see that you are motivated and have initiative. Some action words include: **achieved**, **managed**, **created**, **improved**, **resolved**, etc.

**3. Focus on your outcomes, not your responsibilities.** When listing relevant work experience, state the positive outcomes that your direct actions had on the success of a project. You can use the following template to create your impact statements.

<action verb> <noun> from <data> in order to/which led to <impact>

For example, "*Implemented a cost-saving initiative that reduced expenses by $50,000 annually*."

**4. Focus on the job role youre applying for.** If the job youre applying for is a technical management role, list work experience which demonstrates your leadership and communication skills. Cater the work experience outcomes to the role you want to achieve. For example: "*Managed a cross-functional team of 10 employees to successfully launch a new product, resulting in a 50% increase in sales.*"

**5. Use data and statistics where possible.** If you have tangible values, include them. For example, if you refactored a legacy codebase to be more modern and this led to a 35% reduction in the codebase size, state that. You can say *refactored Dojo legacy codebase into React, which led to a 35% reduction in the package size*.

When writing about your work experience, its important to use words that positively reflect the outcomes of your actions. Words like **achieved, improved, trained, resolved, launched, and built** indicate a positive outcome was achieved as a result of your actions. These words are also specific and allow you to focus on stating the impact you had.

There are also some words or phrases you shouldnt use to describe your work experience or skills.

**Dont use** business or technology **buzzwords** to catch a recruiters eye. These words are often overused and dont add value.

Secondly, **omit words that oversell or promote yourself**. While a resume is essentially an ad campaign for your career, you want to avoid using words or phrases which are too broad, such as **go-getter, go-to person, and detail-oriented**.

A few other examples of words and phrases you should omit from your resume include **hard worker, think outside the box, assisted, utilized, worked on, and something**. These can have a negative impact on your resume and may cause you to be rejected. These words dont do anything to inform the recruiter of the direct impact you had on the success of a project. Theyre vague and overused, so they should be avoided.

When writing your work experience, its important to create these statements **without a main subject**, or, in other words, dont use ** I**.

Instead of writing *I improved the robustness of the timing optimization engines to 95% and its performance to 2x.*, I omitted the subject I and began with the action verb. So I transformed this statement into *Improved the robustness of the timing optimization engines to 95% and its performance to 2x.*. This clearly illustrates your impact on the success of a project.

There are a lot of words in your resume, and the way you use them determines the overall success or failure of your application. Understanding this is critical to finding an appropriate workplace and ensuring that your resume does not get deleted into oblivion.

Choose your words carefully, be conscious of their implication on the impact of your resume and in no time you will have a great first impression on your potential employer!

*Thanks for reading. Check out* *my latest resume* *to see how I used the words there.*

**Awards** are achievements that show your ability to excel in the workplace, and they can add value to your resume.

If you were working as a software engineer at a big tech company and you received two awards from your managers, you could have an Awards section on your resume.

To list an award, list the award name, award description, presenter name, title and company, and month and year.

If you don't have awards, that's okay, and you don't need to list awards on your resume in order to grab a recruiter's attention. They're simply a nice additive to list if you do receive one.

**Certifications** are another area that can showcase your skills and achievements.

Certifications are often achieved through the completion of an online or in-person course or training.

I love taking courses on platforms like LinkedIn Learning and Udemy because they allow me to add a certification to my LinkedIn profile. These can show potential employers that you enjoy continued education, you're reliable and like to see your work through to the end.

Generally, you might need to list all of the details of a certification, such as the name, platform or company, year and month.

However, if you don't have a lot of room left on your resume or if you have a lot of certifications, you can simply state the name. If you omit these details, be prepared to answer questions about them during an interview.

If you're new to the industry or you're looking to switch industries and don't have a lot of work experience, certifications are a great way to learn new skills and showcase your enthusiasm for learning.

I used to list Awards and Certifications on my CV when applying for jobs after my Master's degree because I didn't have much work experience. But after some years of working, I don't list them on my resume anymore. I keep selected Awards and Certifications on my LinkedIn profile.

]]>Today, having a professional online presence is as essential as a good resume to land your dream job. Just because you are not in the office all day doesnt mean you dont have to look professional.

Here are some tips on how to build a professional online presence for tech job hunting.

LinkedIn is one of the most noteworthy job hunting and professional networking websites, so having a complete LinkedIn profile can help you receive a job interview.

When I was job hunting, I used LinkedIn as a way to search for open roles.

**LinkedIn is a virtual resume**. It gives recruiters an overview of your relevant work experience and skills, so if you maintain an online presence with LinkedIn, **you must have a professional and comprehensive profile**.

You can link your LinkedIn profile on your resume to tell recruiters that there is more professional information about you online.

First, you should have an up-to-date and

**professional-looking****photo**. You dont need to spend much money on a professional headshot. You can simply have a friend or family member take a few photos of you wearing something professional. This will ensure you capture a recruiters attention.Second, you should always list your

**full name**. LinkedIn is a professional networking site, so you should refrain from using nicknames.Third, list your

**current job title**and employer. This will allow a recruiter to see where youre currently employed and what you do.If you have any

**awards**or**certifications**, you should list them on your profile.If you write

**blog posts**, LinkedIn is a great place to share and link those as well.Ensure that your

**skills**are accurate and up to date so recruiters with relevant open positions can contact you.You can also ask your colleagues to recommend you on LinkedIn. Having

**testimonials**from colleagues can improve your chances of being contacted by a recruiter.

Having an active LinkedIn presence can be a great way to land a job interview. Treat your LinkedIn profile as an extension of your resume, and youll be contacted by recruiters in no time.

Check out my LinkedIn profile to see how I am doing with it.

GitHub is one of the most popular websites for building an online presence in the tech industry. It allows you to showcase your best **projects**, contribute to open sources and connect with **developers** worldwide.

Having several projects on GitHub, which **demonstrate your technical skills** can improve your chances of landing a job interview.

For example, if you list C++ or Python on your resume, you may want to have a few projects on GitHub that showcase these skills.

Creating a GitHub profile with several completed projects can be time-consuming. And not everyone has the luxury of creating a comprehensive set of repositories.

Your success doesnt depend upon having a GitHub profile. Its simply a nice-to-have, which can convince a recruiter that you will be an excellent fit for the role.

I don't showcase much on my GitHub profile. I use it mainly for storing my C++ solutions to Leetcode challenges.

Creating a personal portfolio or website is a wonderful way to provide more information about yourself, and it can also **demonstrate your technical skills**. If your strongest front-end development skills are with React, you might want to build your portfolio using the Library.

Building a personal website using the technologies youre comfortable with allows you to demonstrate the skills on your resume and gives you a place to be a bit more creative.

While resumes are meant to be professional and clean, a personal website gives you the creative license to let your imagination run wild.

Creating a personal portfolio can be time-consuming and is not required for landing a job interview. I received job offers without having a personal website. Theyre nice-to-haves, but by no means required to be successful.

My personal website is more about blogging, not much about tech skills.

An active online presence can be a great way to land a job interview.

Though GitHub and a personal portfolio or website are nice to have, your LinkedIn profile should be treated as an extension of your resume, and youll be contacted by recruiters immediately.

*Thanks for reading. Check out my online presence on* *LinkedIn* *and* *my personal website**.*

The most relevant content will change depending on the amount of relevant work experience you have.

If you're a recent high school or college graduate, you may want to list your education section towards the top of your resume as you might not have any relevant work experience.

On the other hand, if you've been in the industry for several years and have accumulated a lot of relevant work experience, you'll want to prioritize this section.

Secondly, your **contact information** should be readily available, complete, and easy to locate.

But how you choose to display these sections on your resume can change depending upon which presentation **style** you wish to use.

The traditional resume layout is vertical with your name and contact information at the top followed by the section you wish to showcase.

When building my resume, I had several relevant jobs, so I chose to highlight my work experience section above my education section.

You might also do a horizontal layout with a **sidebar** on the left or right-hand side containing your name, contact information, and tertiary information such as your skills or awards.

The sidebar would span the entire vertical height of your resume and take up about a third of the overall page width.

**The main content area** containing work experience, or education would also span the entire vertical height but would fill two thirds of the page width.

The main goal when building your resume layout is to put the primary content at the top followed by the secondary and tertiary information.

*Thanks for reading. Check out* *my latest resume* *to see how I lay it out.*

**Education** can be one of the trickiest sections of your resume to get right. We live in a day and age where you dont need a college degree to land a job. And while this is wonderful, it can be tricky to list your education on your resume.

How long youve been in the industry will govern the layout of your resume.

**If youre a recent high school or college graduate**, you may want to list your education at the top of your resume, as you probably dont have any relevant work experience.

**If you have internships or relevant projects** which were completed during your degree, you can list these as well, and you may choose to prioritize those above your education, depending upon the relevancy.

**If you have a few years in the industry** like me, you might choose to move the education section underneath relevant work experience.

**If youve graduated from college**, you should list your college name, year of graduation, and degree. You can also include your major and minor.

Tip:if you choose to include your GPA (grade point average) you should only include this if youve achieved above 3.0.

**As a recent graduate**, you can also include any honors or awards you may have received.

**If you have a second college degree**, list them in reverse chronological order, so that the most recent degree is listed at the top.

**If you have a college degree unrelated to the field youre applying for**, it might still be listed. However, you should prioritize relevant work experience over education.

The goal is to put the most relevant information towards the top of your resume.

**If you attended college but never completed the program**, you should only include this information if its relevant to the role youre applying for.

**If you have never finished your college degree**, but the coursework is relevant to the role that youre applying for, you have a couple of options.

*First*, you can list the college name and location with no other details.

(If you believe that adding the months and years you attended the program or your GPA are relevant, you may choose to include those as well.)

*Second*, you can mention some of the coursework youve taken which would help you succeed in this role.

For example, if you attended three out of four years of a computer science degree, you can list the college name, dates attended, city, state, and the number of credits completed. You can even list the specific course names, such as *C++ Programming*.

**If you didnt attend college but instead attended a coding boot camp**, you should include the boot camp name, program name, month and year attended, as well as city and state.

Its also a great idea to include links to the projects youve built during the boot camp program to showcase the skills youve learned.

**If you have never attended college or any educational program**, you can omit the education section, and instead focus on your accomplishments in the workplace which would directly relate to this role.

Your goal should be to convince a recruiter that your work performance is outstanding and you will add value to the company.

**If you have never attended college and have no work experience**, you may want to take online courses in the industry to which youre applying. This will allow you to list some achievements on your resume.

**LinkedIn Learning** offers many affordable online courses, and, once completed, you can add a badge of completion to your LinkedIn profile. This will significantly strengthen your position within an applicant pool.

*Finally, everything you listed in the education section must be consistent.*

For example, when I applied for a *blockchain* company, I decided to list my Masters thesis in the education section. Because it was about *cryptography*. Otherwise, my resume had nothing to match the positions requirements.

Since I listed the thesis for my Master's degree in the education section, I had to list the theses for my Bachelors and Ph.D. as well.

Understanding the best format and layout to showcase your education will improve your chances of getting an interview. No matter what background you come from, or whether you have formal or informal educational training, you should always include any relevant education on your resume.

*Thanks for reading. I hope it is helpful. Check out* *my latest resume* *to see how I filled in my Education section.*

Sometimes, your location will make or break whether you get a job interview. Some companies are looking for a local candidate, while others are more open to candidates from all across the world. So it's important to list your contact information in a prominent location.

But **which contact information should you include on your resume?**

The first piece of information that you list should be your **full name**.

You may use your legal first name, or if you typically go by a shortened version, you may list that too.

For example, if your name is Katherine, but you typically go by Kate, it's appropriate to include Kate as your first name, but you shouldn't include your nickname. It's important to keep your resume formal.

The second piece of contact information you should include is your **phone number**.

You can list your home and cell phone numbers, but it's important to only list phone numbers where you can readily accept a recruiter's call.

You shouldn't list your work phone number if your current employer is not aware that you're searching for a job because it's generally unprofessional to receive a recruiter's phone call at your current position.

Third, you should include your **mailing address**. You can choose to include your complete mailing address, or simply, the city and state.

When I was creating my resume for jobs in Denmark, I chose to include my full mailing address.

If you're applying for international roles, it is crucial that you include the country you're currently residing in.

Fourth, you'll want to provide your **email address**. When including your email, it's important that you use a professional one. An example might be nhut@nhutnguyen.com.

Lastly, you may want to include a link to your **personal website** or **portfolio**, or a link to your professional network profile, like **LinkedIn**.

This can give recruiters a more comprehensive overview of who you are without having to add extraneous or irrelevant information to your resume.

Contact information is one of the most important aspects of your resume, and should be **complete**, **up-to-date**, and **professional**. This will ensure you make a great first impression and provide a recruiter with sufficient means to contact you.

*Thanks for reading. Check out* *my latest resume* *to see how I put my contact information there.*

Understanding how to list your work experience on your resume can make or break whether or not you receive an interview. Relevant work experience is often more important to a recruiter than your education, so its important to know what to list and what to omit.

**If you are a recent graduate**, you might not have any relevant full-time work experience. But if you have successful group projects or internships, you can list them here. If you dont have any group projects or internships to showcase, you can skip this section completely.

**If you have several years in the industry**, you should list the most relevant roles in *reverse chronological order* with the most recent role listed first.

You can list work experience with the **company name**, **job title**, **city and state**, and **months and years** worked.

After writing the general information for your work experience, its time to add a bit more context. You can do this by adding three to four bullet points underneath the experience to describe the role in further detail.

The first tip for creating impactful work experience statements is to state **the outcomes you achieved** over the responsibilities you had during this job role. Stating impact over logistics will leave a much better impression on a recruiter.

For example, instead of stating, *developed the user interface for meeting software*, you should state, *updated the legacy codebase from Dojo to React to deliver features more quickly*.

Use words like **achieved, earned, increased, decreased, modernized, and resolved**.

When adding another impact statement to your work experience, its important to make it feel unique. You should try to use different action words for each statement.

Tip two is to quantify your impact statements wherever possible by adding data.

For example, instead of stating, *refactored the login component to make the join process more performant*, you could state, *refactored the login component to reduce the join process from* *3 seconds**to* ** 0.5 seconds**.

By stating actual data, your statements will have a much higher impact.

Tip three is to avoid using personal pronouns such as I or me. So instead of stating, I trained two new developers, simply state, quickly onboarded two new developers and mentored them during their first development sprint.

Lastly, **avoid summarizing what your company does**. You are the applicant for this job so your resume should focus on you and your work, not the company and their work.

Work experience is one of the most important sections on your tech resume. Knowing what and how to put it in your resume will help you land an interview with the company of your dreams.

Always state the impact over responsibilities and quantify this impact where possible.

*Thanks for reading. Check out* *my latest resume* *to see how I put my work experience there.*

**Fitting all the content within one page** was always one of my biggest challenges.

If you just start applying for the first jobs, you might not have enough work experience and skills to fill in an entire page.

On the other hand, for those with five or six years in the industry, it can feel overwhelming to fit all of your content into one page.

It's important to stick to the resume length rule:

If you have

**less than seven years**of experience in an industry, your resume should be restricted to**one page**.If you have

**more than seven years**of experience, you may extend this limit to include**additional pages**, depending upon the number of years in the industry.

To keep your resume to one or two pages, it's essential to be **clear** and **concise**. Don't delve into long-winded descriptions of your relevant work experience.

Everyone's resume will be different because your resume tells your professional story. Thus, you have the ability to play with different formats to achieve the optimal length.

Your resume might have sections that your coworker won't have. The important thing is that your resume lists all **relevant** and **up-to-date** information and presents the best possible representation of you.

Understanding resume length will ensure that you include relevant information focused on achievements and will give you a leg-up on the competition.

*Check out* *my latest resume* *to see how it fits on one page.*

Like most people, when applying for jobs, I was applying for many different positions and possibly to more than one company in the same industry.

That means many candidates are applying for one single position. And you have to ensure that you put relevant skills in your tech resume, so you can differentiate yourself from the competition.

The problem is most people dont know whats relevant or not when it comes to skills. In this article, well discuss what skills you should include on your tech resume and how those skills will help you stand out from other candidates.

The skills you list on your *tech* resume will differ slightly from those youd find on the resume of a candidate for a *marketing* role.

**Soft skills** are skills that apply to every job. They include skills such as *leadership*, *communication*, and *creative thinking*.

In contrast, **hard skills** are the skills that qualify you for a particular job role. In the tech industry, they would include skills such as **Java**, **Ruby**, **Python** or **C++**.

You can showcase your soft skills in the work experience impact statements instead of listing them out.

In college, I took a course in Java Programming. On my old resume, I used to list Java as a programming skill I was proficient in. But the more time that passed, the more Java I forgot, so I decided to remove Java because it no longer represents my current skillset (C++).

The rule of thumb is if you cant code during an interview in this programming language or answer questions about the technology, you shouldnt list it on your resume.

For example, if youve worked with C++ for eight years and understand its strength, you might list your advanced proficiency with the language.

In contrast, perhaps youve only worked with JavaScript for a year. And while you can get by with it, youre not as proficient as you are with C++. You might state you have intermediate proficiency with JavaScript.

Use words like **advanced**, **intermediate**, and **basic** to denote varying competency levels. This will help your recruiter and perhaps your interviewer determine whether youll be a good fit for the role at hand.

For example, if you have skills in both design and development, you can choose to break them out into these two subsections.

You can list a combination of technologies, languages, and ideologies to convey your skillset.

If youre only listing technical skills, you can also break these up into **subsections**, like *tools*, *languages*, *technologies*, and *processes*.

It can be tempting to list technologies or languages which are highly covetable in the tech industry or for a specific job role. However, you should **never list** a technology or a language **you have not had experience** with unless you denote your proficiency level.

To build credibility, you need to show off only the skills and experience that are relevant to a particular job.

*Thanks for reading. Check out* *my latest resume* *to see how I put my software development skills there.*

Isn't a resume the same as a CV?

The short answer is **no**. A resume and a CV are two **different** documents.

The main differences between a CV and a resume are **length** and **layout**.

A **CV**, or **Curriculum Vitae**, translates to a course of life in Latin and is an in-depth explanation of your achievements.

CVs can span two or more pages covering topics like **education**, **accomplishments**, **awards**, **publications** and **work** history. CVs should be organized chronologically and the format should be fixed.

When I applied for Ph.D. positions worldwide, my CV was three pages long.

In contrast, a **resume** is a **concise** document, one to two pages which exemplifies aspects of your relevant work experience and skills.

A resume's goal is to present the highlight reel of your career and help you stand out from the crowd.

Resumes can have various formats to showcase your **most relevant** experiences.

Resumes are preferred in the United States and Canada, and the CV is preferred in much of Europe and the UK.

Though some recruiters in Denmark sometimes ask me for a CV, I keep it concisely within one page.

Pay attention to which type of document the recruiters tell you to apply for the position and prepare it carefully to ensure you have the best possible chances of getting an interview.

*Check out* *my latest resume* *to see how I put my CV's content there.*

My latest tech resume.

A good example of a resume for a software engineer.

Learn how a modern resume is structured and words are used.

You will get a PDF file in one page.

You also get an email telling you how it is created.

Get it on Gumroad and create your best resume!

]]>On average, recruiters spend about 7.5 seconds scanning your resume. This means you must ensure the most relevant information is at the top.

It is important to remember that a recruiter is looking for **reasons not to hire you** instead of reasons to hire you. They aim to find the best candidates to present to the hiring manager.

There are a few tips for capturing a recruiters attention.

**First, keep your layout simple and organized**. It is much easier for a recruiter to quickly scan your resume if you have clearly labeled sections.

**Second, understand which format will showcase you the best**. There are three formats we can use to build our resume.

The first is a **reverse chronological format**, the **most common** format.

In this format, you emphasize your work experience by listing the most recent first. The work experience section is subsequently followed by skills and education.

This format is great for people with any level of work experience. Whether you are a student looking for your first job, or an experienced candidate with many years in the industry, the reverse chronological format is always a safe and familiar choice.

This format is also great for people without large gaps in their employment history, and who are looking to stay in the same industry or obtain a similar job to their current role.

There are however some downsides that come with the reverse chronological format. Since this is the most widely used resume format, its more challenging to stand out from the rest of the candidate pool. And if you have a significant gap in your employment history or no relevant work experience, this format might draw attention to those areas.

The second format you can use is the **functional or skills-based format**, where you move the skills section to the top of the resume.

This is **the least popular** resume format and can be more time-consuming for recruiters to read.

The functional resume format is really great for people who have a vast amount of skills because it allows you to showcase the things you are good at.

This format is also great if you have a gap in your employment history or are looking to make a career change, as the recruiter wont immediately focus on your work experience.

Keep in mind that the functional resume format is the least often used format, and as a result, your recruiter may need to familiarize themselves with it.

The last is the **combination format**, in which you blend the reverse chronological and functional resume formats.

In this format, you equally emphasize work experience and skills. This format works great for people with various skills and experiences. However, it requires you to have enough skills and work experience to look complete.

When building my resume, I chose the combination format because as a mid-level software engineer, I have a backlog of skills and work experience to showcase.

If you are a student or entry-level candidate, select the reverse chronological format, as you might not have many skills to highlight.

If you are a senior candidate, you can safely pick any one of the three resume formats, as you have enough work experience and skills to feature.

The last tip is to avoid the typical resume red flag, **omitting dates**.

It is vital to ensure all of your work experiences have dates. When you omit dates from your resume, it can indicate to a recruiter that you are trying to hide something.

When listing dates, you should always list the month and year of your employment, or you risk short-selling yourself.

For example, assume you worked at a company from January 2018 to December 2019. If you only list the years, it assumes you worked for only one year. Listing the month and year indicates that you have two years of experience with the company.

By leveraging the appropriate resume format, sticking to a clean and organized hierarchical layout, and listing detailed dates for your education and work experience, you will be one step closer to capturing your recruiters attention.

*Thanks for reading. I hope it is helpful. Check out* *my latest resume* *here* *to see how it was organized.*

If you are a foreigner in Denmark, you must always be available for a career change. Especially with those who are working as software developers like me in Copenhagen, changing jobs happens every 34 years.

A resume is the first thing you need to apply for a job, and having a complete resume will differentiate you from the candidate pool.

Here are why your resume is the most important thing when applying for a job.

The employers must read your resume to decide if you are a suitable candidate for further consideration.

This process will filter out inappropriate candidates. The top 5 or 10 might be called to the next step.

Be different. Be you. Do not make your resume look similar to others.

It details your previous work experience, your education, your skill set and your accomplishments.

If what you advertised in your resume does not match what the team expected, you will be canceled out.

Both hard skills and soft skills are considered. You must adjust your resume according to the job description to show relevant information only.

If you are applying for a tech position, remember to list only the tech stack related to the job. Do not try to list everything.

The primary purpose of your resume is to land you a job interview where you can show an employer who you are and why you are the best fit for the role.

When applying for tech jobs (like *software engineers*) in top companies, hundreds of candidates apply for the same position. You need to be a standout both in the first round and in the next rounds of the interviews.

Many employers will use your resume as a guideline during each interview. Having a great resume will help you win a job interview.

You never know when you have to change jobs.

Thousands of jobs have been changed during the pandemic and after that. Even today. My job was also changed due to that scenario.

An up-to-date resume will help you not be stressed of trying to throw in together at the last minute.

Be prepared. Listen to the job market. Learn new skills. Update your resume. Use it when needed.

I came from Vietnam. My academic CV helped me land a job as a Ph.D. student in Denmark.

When I switched to work in the industry after the Ph.D., I updated my 3-pages CV into a one-page resume. I have constantly been updating my resume and my brand on LinkedIn. It helped me stand out among the candidates whenever I applied for a new job here.

A complete resume will allow you to interview with many companies and ultimately land a great job.

Whether you are changing careers or have just graduated from a coding boot camp, you should build a great resume that earns you several job offers.

*Thanks for reading. Check out* *my latest resume* *for an example of a tech resume.*

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 = 4
Output: 8
Explanation: 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 = 10
Output: 91
```

`1 <= boxTypes.length <= 1000`

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

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

.

```
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int maximumUnits(vector<vector<int>>& boxTypes, int truckSize) {
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:
8
91
```

Runtime:

`O(NlogN)`

, where`N = boxTypes.length`

.Extra space:

`O(1)`

.

Given an integer array `nums`

, return an array `answer`

such that `answer[i]`

is equal to the product of all the elements of nums except `nums[i]`

.

The product of any prefix or suffix of `nums`

is guaranteed to fit in a 32-bit integer.

You must write an algorithm that runs in `O(n)`

time and without using the division operation.

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

```
Input: nums = [-1,1,0,-3,3]
Output: [0,0,9,0,0]
```

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

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

.The product of any prefix or suffix of

`nums`

is guaranteed to fit in a 32-bit integer.

**Follow up**: Can you solve the problem in `O(1)`

extra space complexity? (The output array does not count as extra space for space complexity analysis.)

To avoid division operation, you can compute the prefix product and the suffix one of `nums[i]`

.

```
#include <vector>
#include <iostream>
using namespace std;
vector<int> productExceptSelf(vector<int>& nums) {
const int n = nums.size();
vector<int> prefix(n);
prefix[0] = 1;
for (int i = 1; i < n; i++) {
prefix[i] = prefix[i - 1] * nums[i - 1];
}
vector<int> suffix(n);
suffix[n - 1] = 1;
for (int i = n - 2; i >= 0; i--) {
suffix[i] = suffix[i + 1] * nums[i + 1];
}
vector<int> answer(n);
for (int i = 0; i < n; i++) {
answer[i] = prefix[i] * suffix[i];
}
return answer;
}
void print(vector<int>& nums) {
for (auto& v : nums) {
cout << v << " ";
}
cout << endl;
}
int main() {
vector<int> nums = {1, 2, 3, 4};
auto answer = productExceptSelf(nums);
print(answer);
nums = {-1, 1, 0, -3, 3};
answer = productExceptSelf(nums);
print(answer);
}
```

```
Output:
24 12 8 6
0 0 9 0 0
```

Runtime:

`O(n)`

, where`n = nums.length`

.Extra space:

`O(2n)`

.

`answer`

to store the prefix productIn the solution above you can use directly vector `answer`

for `prefix`

and merge the last two loops into one.

```
#include <vector>
#include <iostream>
using namespace std;
vector<int> productExceptSelf(vector<int>& nums) {
const int n = nums.size();
vector<int> answer(n);
answer[0] = 1;
for (int i = 1; i < n; i++) {
answer[i] = answer[i - 1] * nums[i - 1];
}
int suffix = 1;
for (int i = n - 2; i >= 0; i--) {
suffix *= nums[i + 1];
answer[i] *= suffix;
}
return answer;
}
void print(vector<int>& nums) {
for (auto& v : nums) {
cout << v << " ";
}
cout << endl;
}
int main() {
vector<int> nums = {1, 2, 3, 4};
auto answer = productExceptSelf(nums);
print(answer);
nums = {-1, 1, 0, -3, 3};
answer = productExceptSelf(nums);
print(answer);
}
```

```
Output:
24 12 8 6
0 0 9 0 0
```

Runtime:

`O(n)`

, where`n = nums.length`

.Extra space:

`O(1)`

.

Given the `head`

of a linked list, remove the `n-th`

node from the end of the list and return its head.

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

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

```
Input: head = [1,2], n = 1
Output: [1]
```

The number of nodes in the list is

`sz`

.`1 <= sz <= 30`

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

.`1 <= n <= sz`

.

**Follow up**: Could you do this in one pass?

```
#include <iostream>
#include <vector>
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) {}
};
using namespace std;
ListNode* removeNthFromEnd(ListNode* head, int n) {
vector<ListNode*> nodes;
ListNode* node = head;
while (node)
{
nodes.push_back(node);
node = node->next;
}
node = nodes[nodes.size() - n];
if (node == head) {
head = node->next;
} else {
ListNode* pre = nodes[nodes.size() - n - 1];
pre->next = node->next;
}
return head;
}
void printList(ListNode *head) {
ListNode* node = head;
cout << "[";
while (node) {
cout << node->val << ",";
node = node->next;
}
cout << "]\n";
}
int main() {
ListNode five(5);
ListNode four(4, &five);
ListNode three(3, &four);
ListNode two(2, &three);
ListNode one(1, &two);
auto head = removeNthFromEnd(&one, 2);
printList(head);
head = removeNthFromEnd(&five, 1);
printList(head);
head = removeNthFromEnd(&four, 1);
printList(head);
}
```

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

Runtime:

`O(sz)`

, where`sz`

is the number of nodes in the list.Extra space:

`O(sz)`

.

The distance between the removed node and the end (`nullptr`

) of the list is always `n`

.

You can apply the two-pointer technique as follows.

Let the slower runner start after the faster one `n`

nodes. Then when the faster reaches the end of the list, the slower reaches the node to be removed.

```
#include <iostream>
#include <vector>
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) {}
};
using namespace std;
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* fast = head;
for (int i = 0; i < n; i++) {
fast = fast->next;
}
if (fast == nullptr) {
return head->next;
}
ListNode* slow = head;
while (fast->next)
{
slow = slow->next;
fast = fast->next;
}
slow->next = slow->next->next;
return head;
}
void printList(ListNode *head) {
ListNode* node = head;
cout << "[";
while (node) {
cout << node->val << ",";
node = node->next;
}
cout << "]\n";
}
int main() {
ListNode five(5);
ListNode four(4, &five);
ListNode three(3, &four);
ListNode two(2, &three);
ListNode one(1, &two);
auto head = removeNthFromEnd(&one, 2);
printList(head);
head = removeNthFromEnd(&five, 1);
printList(head);
head = removeNthFromEnd(&four, 1);
printList(head);
}
```

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

Runtime:

`O(sz)`

, where`sz`

is the number of nodes in the list.Extra space:

`O(1)`

.

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

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:
2
16
```

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.

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: 0
Explanation: s is already good.
```

```
Input: s = "aaabbbcc"
Output: 2
Explanation: 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: 2
Explanation: 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 be different.

One way of doing that is 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 to 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:
0
2
2
```

Runtime:

`O(N)`

, where`N = s.length`

;Extra space:

`O(1)`

since`26`

is not a big number.

There are several cards arranged in a row, and each card has an associated number of points. The points are given in the integer array `cardPoints`

.

In one step, you can take one card from the beginning or from the end of the row. You have to take exactly `k`

cards.

Your score is the sum of the points of the cards you have taken.

Given the integer array `cardPoints`

and the integer `k`

, return the maximum score you can obtain.

```
Input: cardPoints = [1,2,3,4,5,6,1], k = 3
Output: 12
Explanation: After the first step, your score will always be 1. However, choosing the rightmost card first will maximize your total score. The optimal strategy is to take the three cards on the right, giving a final score of 1 + 6 + 5 = 12.
```

```
Input: cardPoints = [2,2,2], k = 2
Output: 4
Explanation: Regardless of which two cards you take, your score will always be 4.
```

```
Input: cardPoints = [9,7,7,9,7,7,9], k = 7
Output: 55
Explanation: You have to take all the cards. Your score is the sum of points of all cards.
```

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

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

.`1 <= k <= cardPoints.length`

.

`k`

consecutive cards of interestAssume there are `N`

cards in `cardPoints`

. You might be interested in only `2k`

cards in this problem.

Any card you take is either in the first `k`

cards `cardPoints[0, ..., k-1]`

or in the last `k`

cards `cardPoints[N-k, ..., N-1]`

.

If you concatenate the last part with the first one like this `cardPoints[N-k, ..., N-1, 0, ..., k-1]`

, the problem turns into computing the maximum sum of the `k`

consecutive cards in that new array.

For `cardPoints = [1,2,3,4,5,6,1]`

and `k = 3`

, concatenating the last `3`

cards with the first `3`

cards you get the array `[5,6,1,1,2,3,4]`

.

The maximum sum of the `3`

consecutive cards is `sum([5,6,1]) = 12`

.

```
#include <iostream>
#include <vector>
using namespace std;
int maxScore(vector<int>& cardPoints, int k) {
vector<int> cards(cardPoints.end() - k, cardPoints.end());
cards.insert(cards.end(), cardPoints.begin(), cardPoints.begin() + k);
int maxSum = 0;
for (int i = 0; i <= k; i++) {
int sum = 0;
for (int j = 0; j < k; j++) {
sum += cards[i + j];
}
maxSum = max(maxSum, sum);
}
return maxSum;
}
int main() {
vector<int> cardPoints{1,2,3,4,5,6,1};
cout << maxScore(cardPoints, 3) << endl;
cardPoints = {2,2,2};
cout << maxScore(cardPoints, 2) << endl;
cardPoints = {9,7,7,9,7,7,9};
cout << maxScore(cardPoints, 7) << endl;
}
```

```
Output:
12
4
55
```

Runtime:

`O(k^2)`

.Extra space:

`O(2k)`

.

When `k`

is large (it can equal `cardPoints.length`

), the solution above is slow due to runtime complexity `O(k^2)`

.

It is because there are many recomputations when computing the `sum`

of each `k`

consecutive cards.

You can save this runtime by keeping the common `(k-1)`

-sum between two neighbor `k`

-sums.

The sum `6 + 1`

are computed in both sums `5 + 6 + 1`

and `6 + 1 + 1`

in the array `[5,6,1,1,2,3,4]`

.

Assume you have computed the sum `5 + 6 + 1 = 12`

. To compute the next sum `6 + 1 + 1`

, keep the sum `6 + 1`

from previous one by subtracting `12 - 5 = 7`

. Then add it with the new card's points `7 + 1 = 8`

.

The value `k`

in this example is not too large to see the effect but I believe you can see how it helps when `k`

is very large.

On the other hand, you do not have to use extra space for the concatenation. You can use the modulo operator `%`

on the indices.

```
#include <iostream>
#include <vector>
using namespace std;
int maxScore(vector<int>& cardPoints, int k) {
int maxSum = 0;
int sum = 0;
// Compute the sum of the last k cards
for (int i = cardPoints.size() - k; i < cardPoints.size(); i++) {
sum += cardPoints[i];
}
maxSum = max(maxSum, sum);
// Compute the other sums
for (int i = cardPoints.size() - k + 1; i <= cardPoints.size(); i++) {
sum = sum - cardPoints[i - 1] + cardPoints[(i - 1 + k) % cardPoints.size()];
maxSum = max(maxSum, sum);
}
return maxSum;
}
int main() {
vector<int> cardPoints{1,2,3,4,5,6,1};
cout << maxScore(cardPoints, 3) << endl;
cardPoints = {2,2,2};
cout << maxScore(cardPoints, 2) << endl;
cardPoints = {9,7,7,9,7,7,9};
cout << maxScore(cardPoints, 7) << endl;
}
```

```
Output:
12
4
55
```

Runtime:

`O(k)`

.Extra space:

`O(1)`

.

Given a positive integer `n`

, generate an `n x n`

matrix filled with elements from `1`

to `n^2`

in spiral order.

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

```
Input: n = 1
Output: [[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,]]
```

Runtime:

`O(n^2)`

, where`n x n`

is the size of the matrix.Extra space:

`O(1)`

.

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 by 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)`

.

Given a string `s`

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

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

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

```
Input: s = "pwwkew"
Output: 3
Explanation: 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.

Whenever you meet a visited character `s[i] == s[j]`

for some `0 <= i < j < s.length`

, the substring `"s[i]...s[j - 1]"`

might be valid, i.e. it consist of only nonrepeating characters.

But in case you meet another visited character `s[x] == s[y]`

where `x < i < j < y`

, the substring `"s[x]...s[y - 1]"`

is not valid because it consists of repeated character `s[i] == s[j]`

.

That shows the substring `"s[i]...s[j - 1]"`

is not always a valid one. You might need to find the right starting position `start >= i`

for the valid substring `"s[start]...s[j - 1]"`

.

For the string `s = "babba"`

:

When you visit the second letter

`'b'`

, the substring`"ba"`

is a valid one.When you visit the third letter

`'b'`

, the substring of interest should be started by the second letter`'b'`

. It gives you the substring`"b"`

.When you visit the second letter

`'a'`

, the substring`"abb"`

is not a valid one since`'b'`

is repeated. To ensure no repetition, the starting position for this substring should be the latter`'b'`

, which leads to the valid substring`"b"`

.The final longest valid substring is

`"ba"`

with length 2.

Example 4 shows the starting position `start`

for the substring of interest `"s[i]...s[j - 1]"`

should be:

```
this_start = max(previous_start, i).
```

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

```
Output:
3
1
3
```

Runtime:

`O(N)`

, where`N = s.length`

.Extra space:

`O(N)`

.

You are given an `m x n`

integer array `grid`

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

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

). The robot can only move either down or right at any point in time.

An obstacle and space are marked as `1`

or `0`

respectively in `grid`

. A path that the robot takes cannot include any square that is an obstacle.

Return the number of possible unique paths that the robot can take to reach the bottom-right corner.

The test cases are generated so that the answer will be less than or equal to `2 * 10^9`

.

```
Input: obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
Output: 2
Explanation: 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 -> Down
2. 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 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:
2
1
```

Runtime:

`O(m*n)`

, where`m x n`

is the size of the`grid`

.Extra space:

`O(m*n)`

.

International Morse Code defines a standard encoding where each letter is mapped to a series of dots and dashes, as follows:

`'a'`

maps to`".-"`

,`'b'`

maps to`"-..."`

,`'c'`

maps to`"-.-."`

, and so on.

For convenience, the full table for the `26`

letters of the English alphabet is given below:

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

Given an array of strings `words`

where each word can be written as a concatenation of the Morse code of each letter.

- For example,
`"cab"`

can be written as`"-.-..--..."`

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

,`".-"`

, and`"-..."`

. We will call such a concatenation the transformation of a word.

Return the number of different transformations among all words we have.

```
Input: words = ["gin","zen","gig","msg"]
Output: 2
Explanation: 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:
2
1
```

Runtime:

`O(N*M)`

, where`N = words.length`

and`M = words[i].length`

.Extra space:

`O(N)`

.

An underground railway system is keeping track of customer travel times between different stations. They are using this data to calculate the average time it takes to travel from one station to another.

Implement the `UndergroundSystem`

class:

`void checkIn(int id, string stationName, int t)`

- A customer with a card ID equal to
`id`

, checks in at the station`stationName`

at time`t`

. - A customer can only be checked into one place at a time.

- A customer with a card ID equal to
`void checkOut(int id, string stationName, int t)`

- A customer with a card ID equal to
`id`

, checks out from the station`stationName`

at time`t`

.

- A customer with a card ID equal to
`double getAverageTime(string startStation, string endStation)`

- Returns the average time it takes to travel from
`startStation`

to`endStation`

. - The average time is computed from all the previous traveling times from
`startStation`

to`endStation`

that happened directly, meaning a check-in at`startStation`

followed by a check-out from`endStation`

. - The time it takes to travel from
`startStation`

to`endStation`

may be different from the time it takes to travel from`endStation`

to`startStation`

. - There will be at least one customer that has traveled from
`startStation`

to`endStation`

before`getAverageTime`

is called.

- Returns the average time it takes to travel from

You may assume all calls to the `checkIn`

and `checkOut`

methods are consistent. If a customer checks in at time `t1`

then checks out at time `t2`

, then `t1 < t2`

. All events happen in chronological order.

```
Input
["UndergroundSystem","checkIn","checkIn","checkIn","checkOut","checkOut","checkOut","getAverageTime","getAverageTime","checkIn","getAverageTime","checkOut","getAverageTime"]
[[],[45,"Leyton",3],[32,"Paradise",8],[27,"Leyton",10],[45,"Waterloo",15],[27,"Waterloo",20],[32,"Cambridge",22],["Paradise","Cambridge"],["Leyton","Waterloo"],[10,"Leyton",24],["Leyton","Waterloo"],[10,"Waterloo",38],["Leyton","Waterloo"]]
Output
[null,null,null,null,null,null,null,14.00000,11.00000,null,11.00000,null,12.00000]
Explanation
UndergroundSystem undergroundSystem = new UndergroundSystem();
undergroundSystem.checkIn(45, "Leyton", 3);
undergroundSystem.checkIn(32, "Paradise", 8);
undergroundSystem.checkIn(27, "Leyton", 10);
undergroundSystem.checkOut(45, "Waterloo", 15); // Customer 45 "Leyton" -> "Waterloo" in 15-3 = 12
undergroundSystem.checkOut(27, "Waterloo", 20); // Customer 27 "Leyton" -> "Waterloo" in 20-10 = 10
undergroundSystem.checkOut(32, "Cambridge", 22); // Customer 32 "Paradise" -> "Cambridge" in 22-8 = 14
undergroundSystem.getAverageTime("Paradise", "Cambridge"); // return 14.00000. One trip "Paradise" -> "Cambridge", (14) / 1 = 14
undergroundSystem.getAverageTime("Leyton", "Waterloo"); // return 11.00000. Two trips "Leyton" -> "Waterloo", (10 + 12) / 2 = 11
undergroundSystem.checkIn(10, "Leyton", 24);
undergroundSystem.getAverageTime("Leyton", "Waterloo"); // return 11.00000
undergroundSystem.checkOut(10, "Waterloo", 38); // Customer 10 "Leyton" -> "Waterloo" in 38-24 = 14
undergroundSystem.getAverageTime("Leyton", "Waterloo"); // return 12.00000. Three trips "Leyton" -> "Waterloo", (10 + 12 + 14) / 3 = 12
```

```
Input
["UndergroundSystem","checkIn","checkOut","getAverageTime","checkIn","checkOut","getAverageTime","checkIn","checkOut","getAverageTime"]
[[],[10,"Leyton",3],[10,"Paradise",8],["Leyton","Paradise"],[5,"Leyton",10],[5,"Paradise",16],["Leyton","Paradise"],[2,"Leyton",21],[2,"Paradise",30],["Leyton","Paradise"]]
Output
[null,null,null,5.00000,null,null,5.50000,null,null,6.66667]
Explanation
UndergroundSystem undergroundSystem = new UndergroundSystem();
undergroundSystem.checkIn(10, "Leyton", 3);
undergroundSystem.checkOut(10, "Paradise", 8); // Customer 10 "Leyton" -> "Paradise" in 8-3 = 5
undergroundSystem.getAverageTime("Leyton", "Paradise"); // return 5.00000, (5) / 1 = 5
undergroundSystem.checkIn(5, "Leyton", 10);
undergroundSystem.checkOut(5, "Paradise", 16); // Customer 5 "Leyton" -> "Paradise" in 16-10 = 6
undergroundSystem.getAverageTime("Leyton", "Paradise"); // return 5.50000, (5 + 6) / 2 = 5.5
undergroundSystem.checkIn(2, "Leyton", 21);
undergroundSystem.checkOut(2, "Paradise", 30); // Customer 2 "Leyton" -> "Paradise" in 30-21 = 9
undergroundSystem.getAverageTime("Leyton", "Paradise"); // return 6.66667, (5 + 6 + 9) / 3 = 6.66667
```

`1 <= id, t <= 10^6`

.`1 <= stationName.length, startStation.length, endStation.length <= 10`

.- All strings consist of uppercase and lowercase English letters and digits.
- There will be at most
`2 * 10^4`

calls in total to`checkIn`

,`checkOut`

, and`getAverageTime`

. - Answers within
`1e-5`

of the actual value will be accepted.

```
#include <iostream>
#include <unordered_map>
#include <numeric>
#include <vector>
using namespace std;
class UndergroundSystem {
unordered_map< string, vector<int> > _routes;
unordered_map< int, pair<string, int> > _checkIns;
public:
UndergroundSystem() {
}
void checkIn(int id, string stationName, int t) {
_checkIns[id] = make_pair(stationName, t);
}
void checkOut(int id, string stationName, int t) {
const string route = _checkIns[id].first + "-" + stationName;
_routes[route].push_back(t - _checkIns[id].second);
}
double getAverageTime(string startStation, string endStation) {
const string route = startStation + "-" + endStation;
vector<int>& v = _routes[route];
return (double) accumulate(v.begin(), v.end(), 0) / v.size();
}
};
int main() {
UndergroundSystem u;
u.checkIn(45, "Leyton", 3);
u.checkIn(32, "Paradise", 8);
u.checkIn(27, "Leyton", 10);
u.checkOut(45, "Waterloo", 15);
u.checkOut(27, "Waterloo", 20);
u.checkOut(32, "Cambridge", 22);
cout << u.getAverageTime("Paradise", "Cambridge") << endl;
cout << u.getAverageTime("Leyton", "Waterloo") << endl;
u.checkIn(10, "Leyton", 24);
cout << u.getAverageTime("Leyton", "Waterloo") << endl;
u.checkOut(10, "Waterloo", 38);
cout << u.getAverageTime("Leyton", "Waterloo") << endl;
}
```

```
Output:
14
11
11
12
```

- Runtime:
`O(1)`

. - Extra space:
`O(2*N + 2^M * P)`

, where`N`

is the number of customers,`M`

is the number of stations and`P`

is the average number of travels between the stations.

```
#include <iostream>
#include <unordered_map>
using namespace std;
class UndergroundSystem {
unordered_map< string, pair<int, int> > _routes;
unordered_map< int, pair<string, int> > _checkIns;
public:
UndergroundSystem() {
}
void checkIn(int id, string stationName, int t) {
_checkIns[id] = {stationName, t};
}
void checkOut(int id, string stationName, int t) {
const string route = _checkIns[id].first + "-" + stationName;
auto& p = _routes[route];
p.first += t - _checkIns[id].second;
p.second++;
}
double getAverageTime(string startStation, string endStation) {
const string route = startStation + "-" + endStation;
auto& p = _routes[route];
return (double) p.first / p.second;
}
};
int main() {
UndergroundSystem u;
u.checkIn(45, "Leyton", 3);
u.checkIn(32, "Paradise", 8);
u.checkIn(27, "Leyton", 10);
u.checkOut(45, "Waterloo", 15);
u.checkOut(27, "Waterloo", 20);
u.checkOut(32, "Cambridge", 22);
cout << u.getAverageTime("Paradise", "Cambridge") << endl;
cout << u.getAverageTime("Leyton", "Waterloo") << endl;
u.checkIn(10, "Leyton", 24);
cout << u.getAverageTime("Leyton", "Waterloo") << endl;
u.checkOut(10, "Waterloo", 38);
cout << u.getAverageTime("Leyton", "Waterloo") << endl;
}
```

```
Output:
14
11
11
12
```

- Runtime:
`O(1)`

. - Extra space:
`O(2*N + 2^M * P)`

, where`N`

is the number of customers,`M`

is the number of stations and`P`

is the average number of travels between the stations.

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

Implement the `MyHashMap`

class:

`MyHashMap()`

initializes the object with an empty map.`void put(int key, int value)`

inserts a`(key, value)`

pair into the`HashMap`

. If the`key`

already exists in the map, update the corresponding`value`

.`int get(int key)`

returns the`value`

to which the specified`key`

is mapped, or`-1`

if this map contains no mapping for the`key`

.`void remove(key)`

removes the`key`

and its corresponding`value`

if the map contains the mapping for the`key`

.

```
Input
["MyHashMap", "put", "put", "get", "get", "put", "get", "remove", "get"]
[[], [1, 1], [2, 2], [1], [3], [2, 1], [2], [2], [2]]
Output
[null, null, null, 1, -1, null, 1, null, -1]
Explanation
MyHashMap myHashMap = new MyHashMap();
myHashMap.put(1, 1); // The map is now [[1,1]]
myHashMap.put(2, 2); // The map is now [[1,1], [2,2]]
myHashMap.get(1); // return 1, The map is now [[1,1], [2,2]]
myHashMap.get(3); // return -1 (i.e., not found), The map is now [[1,1], [2,2]]
myHashMap.put(2, 1); // The map is now [[1,1], [2,1]] (i.e., update the existing value)
myHashMap.get(2); // return 1, The map is now [[1,1], [2,1]]
myHashMap.remove(2); // remove the mapping for 2, The map is now [[1,1]]
myHashMap.get(2); // return -1 (i.e., not found), The map is now [[1,1]]
```

`0 <= key, value <= 10^6`

.- At most
`10^4`

calls will be made to`put`

,`get`

, and`remove`

.

```
#include <iostream>
#include <vector>
using namespace std;
class MyHashMap {
vector<int> _v;
public:
MyHashMap() : _v(1000001, -1) {
}
void put(int key, int value) {
_v[key] = value;
}
int get(int key) {
return _v[key];
}
void remove(int key) {
_v[key] = -1;
}
};
int main() {
MyHashMap m;
m.put(1, 1);
m.put(2, 2);
cout << m.get(1) << endl;
cout << m.get(3) << endl;
m.put(2, 1);
cout << m.get(2) << endl;
m.remove(2);
cout << m.get(2) << endl;
}
```

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

- Runtime:
`O(1)`

. - Extra space:
`KEY_MAX`

, which is`10^6`

in this problem.

```
#include <iostream>
#include <vector>
using namespace std;
class MyHashMap {
vector<pair<int, int> > _v;
public:
MyHashMap() {
}
void put(int key, int value) {
for (auto& p : _v) {
if (p.first == key) {
p.second = value;
return;
}
}
_v.push_back(make_pair(key, value));
}
int get(int key) {
for (auto& p : _v) {
if (p.first == key) {
return p.second;
}
}
return -1;
}
void remove(int key) {
auto it = _v.begin();
while (it != _v.end()) {
if (it->first == key) {
_v.erase(it);
return;
} else {
it++;
}
}
}
};
int main() {
MyHashMap m;
m.put(1, 1);
m.put(2, 2);
cout << m.get(1) << endl;
cout << m.get(3) << endl;
m.put(2, 1);
cout << m.get(2) << endl;
m.remove(2);
cout << m.get(2) << endl;
}
```

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

- Runtime:
`O(N)`

, where`N`

is the number of keys. - Extra space:
`O(2N)`

.

Given an integer array `arr`

, and an integer `target`

, return the number of tuples `i, j, k`

such that `i < j < k`

and `arr[i] + arr[j] + arr[k] == target`

.

As the answer can be very large, return it modulo `10^9 + 7`

.

```
Input: arr = [1,1,2,2,3,3,4,4,5,5], target = 8
Output: 20
Explanation:
Enumerating by the values (arr[i], arr[j], arr[k]):
(1, 2, 5) occurs 8 times;
(1, 3, 4) occurs 8 times;
(2, 2, 4) occurs 2 times;
(2, 3, 3) occurs 2 times.
```

```
Input: arr = [1,1,2,2,2,2], target = 5
Output: 12
Explanation:
arr[i] = 1, arr[j] = arr[k] = 2 occurs 12 times:
We choose one 1 from [1,1] in 2 ways,
and two 2s from [2,2,2,2] in 6 ways.
```

`3 <= arr.length <= 3000`

.`0 <= arr[i] <= 100`

.`0 <= target <= 300`

.

Find all tuples that satisfy the target sum.

```
#include <vector>
#include <iostream>
using namespace std;
int threeSumMulti(vector<int>& arr, int target) {
const int MOD = 1000000007;
int count = 0;
for (int i = 0; i < arr.size() - 2; i++) {
for (int j = i + 1; j < arr.size() - 1; j++) {
for (int k = j + 1; k < arr.size(); k++) {
if (arr[i] + arr[j] + arr[k] == target) {
count += 1 % MOD;
}
}
}
}
return count;
}
int main() {
vector<int> arr{1,1,2,2,3,3,4,4,5,5};
cout << threeSumMulti(arr, 8) << endl;
arr = {1,1,2,2,2,2};
cout << threeSumMulti(arr, 5) << endl;
}
```

```
Output:
20
12
```

- Runtime:
`O(N^3)`

, where`N = arr.length`

. - Extra space:
`O(1)`

.

Rewrite the condition `arr[i] + arr[j] + arr[k] == target`

as `arr[i] == target - arr[j] - arr[k]`

, then you can reduce one of the `for`

loops by using a map to store the count of the values `arr[i]`

that have been visited.

```
#include <vector>
#include <iostream>
#include <unordered_map>
using namespace std;
int threeSumMulti(vector<int>& arr, int target) {
unordered_map<int, int> m;
const int MOD = 1000000007;
int count = 0;
for (int i = 0; i < arr.size() - 1; i++) {
for (int j = i + 1; j < arr.size(); j++) {
auto it = m.find(target - arr[i] - arr[j]);
if (it != m.end()) {
count = (count + it->second) % MOD;
}
}
m[arr[i]]++;
}
return count;
}
int main() {
vector<int> arr{1,1,2,2,3,3,4,4,5,5};
cout << threeSumMulti(arr, 8) << endl;
arr = {1,1,2,2,2,2};
cout << threeSumMulti(arr, 5) << endl;
}
```

```
Output:
20
12
```

- Runtime:
`O(N^2)`

, where`N = arr.length`

. - Extra space:
`O(N)`

.

Write a function that reverses a string. The input string is given as an array of characters `s`

.

You must do this by modifying the input array in-place with `O(1)`

extra memory.

```
Input: s = ['h','e','l','l','o']
Output: ['o','l','l','e','h']
```

```
Input: s = ['H','a','n','n','a','h']
Output: ['h','a','n','n','a','H']
```

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

.`s[i]`

is a printable ascii character.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
void reverseString(vector<char>& s) {
int i = 0;
int j = s.size() - 1;
while (i < j) {
swap(s[i++], s[j--]);
}
}
void printResult(vector<char>& s) {
cout << "[";
for (char c : s) {
cout << c << ",";
}
cout << "]\n";
}
int main() {
vector<char> s{'h','e','l','l','o'};
reverseString(s);
printResult(s);
s = {'H','a','n','n','a','h'};
reverseString(s);
printResult(s);
}
```

```
Output:
[o,l,l,e,h,]
[h,a,n,n,a,H,]
```

- Runtime:
`O(N)`

, where`N = s.length`

. - Extra space:
`O(1)`

.

Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You must write an algorithm with `O(logn)`

runtime complexity.

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

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

```
Input: nums = [1,3,5,6], target = 7
Output: 4
```

```
Input: nums = [1,3,5,6], target = 0
Output: 0
```

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

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

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

.`nums`

contains distinct values sorted in ascending order.`-10^4 <= target <= 10^4`

.

```
int searchInsert(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left)/2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return right + 1;
}
int main() {
vector<int> nums = {1,3,5,6};
cout << searchInsert(nums, 5) << endl;
cout << searchInsert(nums, 2) << endl;
cout << searchInsert(nums, 7) << endl;
cout << searchInsert(nums, 0) << endl;
nums = {1};
cout << searchInsert(nums, 0) << endl;
}
```

```
Output:
2
1
4
0
0
```

- Runtime:
`O(logN)`

, where`N = nums.length`

. - Extra space:
`O(1)`

.

`std::lower_bound(nums.begin(), nums.end(), target)`

The function does exactly what you want for this problem.

```
int searchInsert(vector<int>& nums, int target) {
return lower_bound(nums.begin(), nums.end(), target) - nums.begin();
}
int main() {
vector<int> nums = {1,3,5,6};
cout << searchInsert(nums, 5) << endl;
cout << searchInsert(nums, 2) << endl;
cout << searchInsert(nums, 7) << endl;
cout << searchInsert(nums, 0) << endl;
nums = {1};
cout << searchInsert(nums, 0) << endl;
}
```

```
Output:
2
1
4
0
0
```

- Runtime:
`O(logN)`

, where`N = nums.length`

. - Extra space:
`O(1)`

.

Write an efficient algorithm that searches for a value `target`

in an `m x n`

integer matrix `matrix`

. This matrix has the following properties:

- Integers in each row are sorted from left to right.
- The first integer of each row is greater than the last integer of the previous row.

```
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
Output: true
```

```
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
Output: false
```

`m == matrix.length`

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

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

.`-10^4 <= matrix[i][j], target <= 10^4`

.

All rows are sorted, so you can perform a binary search on one of them. The only thing is choosing which row to do the searching.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int i = matrix.size() - 1;
while (i >= 0 && target < matrix[i][0]) {
i--;
}
if (i >= 0) {
return binary_search(matrix[i].begin(), matrix[i].end(), target);
}
return false;
}
int main() {
vector<vector<int>> matrix{{1,3,5,7},{10,11,16,20},{23,30,34,60}};
cout << searchMatrix(matrix, 3) << endl;
cout << searchMatrix(matrix, 13) << endl;
}
```

```
Output:
1
0
```

- Runtime:
`O(m + logn)`

, where`m = matrix.length`

,`n = matrix[i].length`

. - Extra space:
`O(1)`

.

There is an integer array `nums`

sorted in non-decreasing order (not necessarily with distinct values).

Before being passed to your function, `nums`

is rotated at an unknown pivot index `k`

(`0 <= k < nums.length`

) such that the resulting array is `[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]`

(0-indexed). For example, `[0,1,2,4,4,4,5,6,6,7]`

might be rotated at pivot index `5`

and become `[4,5,6,6,7,0,1,2,4,4]`

.

Given the array `nums`

after the rotation and an integer `target`

, return `true`

if `target`

is in `nums`

, or `false`

if it is not in `nums`

.

You must decrease the overall operation steps as much as possible.

```
Input: nums = [2,5,6,0,0,1,2], target = 0
Output: true
```

```
Input: nums = [2,5,6,0,0,1,2], target = 3
Output: false
```

`1 <= nums.length <= 5000`

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

`nums`

is guaranteed to be rotated at some pivot.`-10^4 <= target <= 10^4`

.

Find the min element and do the binary search from there. When finding this min element you can check if `target`

is found as well.

```
#include <vector>
#include <iostream>
using namespace std;
bool search(vector<int>& nums, int target) {
if (nums[0] == target) {
return true;
}
int i = 1;
while (i < nums.size() && nums[i - 1] <= nums[i]) {
if (nums[i] == target) {
return true;
}
i++;
}
int r = nums.size() - 1;
while (i <= r) {
int mid = i + (r - i) / 2;
if (nums[mid] == target) {
return true;
} else if (nums[mid] < target) {
i = mid + 1;
} else {
r = mid - 1;
}
}
return false;
}
int main() {
vector<int> nums{2,5,6,0,0,1,2};
cout << search(nums, 0) << endl;
cout << search(nums, 3) << endl;
nums = {1};
cout << search(nums, 1) << endl;
}
```

```
Output:
1
0
1
```

- Runtime:
`O(N)`

, where`N = nums.length`

. - Extra space:
`O(1)`

.

In order to perform the normal binary search, the array must be sorted.

So, if one of the half parts of `nums`

is sorted, you can determine which part to go next based on the `target`

value.

For `nums = [2,5,6,0,0,1,2]`

and `target = 3`

:

- The half part
`[0,0,1,2]`

is sorted. - The
`target = 3`

is out of this part. - You can go next for the part
`[2,5,6]`

. - So on and so on.

One way to identify if a part is sorted is by comparing its ends, e.g. `nums[l] < nums[mid]`

or `nums[mid] < nums[r]`

. In Example 2, `0 < 2`

so you are sure the right half part is sorted.

The only case you are not sure which half part is sorted is when `nums[l] == nums[mid]`

and `nums[mid] == nums[r]`

. Especially when duplications are allowed in this problem.

In this case, you can not go for the normal binary search to any half part. The only thing you can do is shorten the `nums`

, e.g. to `[nums[l+i], ..., nums[r-j]]`

until you can get a new half part sorted.

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

, all `nums[l]`

, `nums[mid]`

and `nums[r]`

are `1`

. There is no clear information for you to know which half part is sorted based on the comparisons between those three values. In this case, you can shorten `nums`

to `[0,1]`

before performing the binary search for any `target`

.

```
#include <vector>
#include <iostream>
using namespace std;
bool search(vector<int>& nums, int target) {
int l = 0;
int r = nums.size() - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (nums[mid] == target) {
return true;
}
if (nums[l] < nums[mid]) {
if (nums[l] <= target && target < nums[mid]) {
r = mid - 1;
} else {
l = mid + 1;
}
} else if (nums[mid] < nums[r]) {
if (nums[mid] < target && target <= nums[r]) {
l = mid + 1;
} else {
r = mid - 1;
}
} else {
while (l <= r && nums[l] == nums[mid]) {
l++;
}
while (l <= r && nums[r] == nums[mid]) {
r--;
}
}
}
return false;
}
int main() {
vector<int> nums{2,5,6,0,0,1,2};
cout << search(nums, 0) << endl;
cout << search(nums, 3) << endl;
nums = {1};
cout << search(nums, 1) << endl;
nums = {1, 0, 1, 1, 1};
cout << search(nums, 0) << endl;
}
```

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

- Runtime: "Generally"
`O(logN)`

, where`N = nums.length`

. The worst case`O(N)`

is when all elements of`nums`

are the same value. - Extra space:
`O(1)`

.

You are given an `m x n`

binary matrix `mat`

of `1`

's (representing soldiers) and `0`

's (representing civilians). The soldiers are positioned in front of the civilians. That is, all the `1`

's will appear to the left of all the `0`

's in each row.

A row `i`

is weaker than a row `j`

if one of the following is true:

- The number of soldiers in row
`i`

is less than the number of soldiers in row`j`

. - Both rows have the same number of soldiers and
`i < j`

.

Return the **indices** of the `k`

weakest rows in the matrix ordered from weakest to strongest.

```
Input: mat =
[[1,1,0,0,0],
[1,1,1,1,0],
[1,0,0,0,0],
[1,1,0,0,0],
[1,1,1,1,1]],
k = 3
Output: [2,0,3]
Explanation:
The number of soldiers in each row is:
- Row 0: 2
- Row 1: 4
- Row 2: 1
- Row 3: 2
- Row 4: 5
The rows ordered from weakest to strongest are [2,0,3,1,4].
```

```
Input: mat =
[[1,0,0,0],
[1,1,1,1],
[1,0,0,0],
[1,0,0,0]],
k = 2
Output: [0,2]
Explanation:
The number of soldiers in each row is:
- Row 0: 1
- Row 1: 4
- Row 2: 1
- Row 3: 1
The rows ordered from weakest to strongest are [0,2,3,1].
```

`m == mat.length`

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

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

.`1 <= k <= m`

.`matrix[i][j]`

is either`0`

or`1`

.

Compute the number of soldiers for each row and sort the rows based on the "weaker row" criteria.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
vector<int> kWeakestRows(vector<vector<int>>& mat, int k) {
using myPair = pair<int,int>;
vector<myPair> v;
for (int i = 0; i < mat.size(); i++) {
int num = 0;
for (int j = 0; j < mat[i].size(); j++) {
num += mat[i][j];
}
v.push_back(make_pair(i, num));
}
sort(v.begin(), v.end(), [](myPair& a, myPair&b){
if (a.second < b.second) {
return true;
} else if (a.second == b.second) {
return a.first < b.first;
}
return false;
});
vector<int> result;
for (int i = 0; i < k; i++) {
result.push_back(v[i].first);
}
return result;
}
void printResult(vector<int>& result) {
cout << "[";
for (int a : result) {
cout << a << ",";
}
cout << "]\n";
}
int main() {
vector<vector<int>> mat{{1,1,0,0,0},
{1,1,1,1,0},
{1,0,0,0,0},
{1,1,0,0,0},
{1,1,1,1,1}};
auto result = kWeakestRows(mat, 3);
printResult(result);
mat = {{1,0,0,0},
{1,1,1,1},
{1,0,0,0},
{1,0,0,0}};
result = kWeakestRows(mat, 2);
printResult(result);
}
```

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

- Runtime:
`O(mn)`

, where`m = mat.length, n = mat[i].length`

. - Extra space:
`O(m)`

.

Standard C++ by default uses dictionary order to compare between such pairs of integers. You can switch the pair items to reduce some code.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
vector<int> kWeakestRows(vector<vector<int>>& mat, int k) {
using myPair = pair<int,int>;
vector<myPair> v;
for (int i = 0; i < mat.size(); i++) {
int num = 0;
for (int j = 0; j < mat[i].size(); j++) {
num += mat[i][j];
}
v.push_back(make_pair(num, i));
}
sort(v.begin(), v.end());
vector<int> result;
for (int i = 0; i < k; i++) {
result.push_back(v[i].second);
}
return result;
}
void printResult(vector<int>& result) {
cout << "[";
for (int a : result) {
cout << a << ",";
}
cout << "]\n";
}
int main() {
vector<vector<int>> mat{{1,1,0,0,0},
{1,1,1,1,0},
{1,0,0,0,0},
{1,1,0,0,0},
{1,1,1,1,1}};
auto result = kWeakestRows(mat, 3);
printResult(result);
mat = {{1,0,0,0},
{1,1,1,1},
{1,0,0,0},
{1,0,0,0}};
result = kWeakestRows(mat, 2);
printResult(result);
}
```

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

- Runtime:
`O(mn)`

, where`m = mat.length, n = mat[i].length`

. - Extra space:
`O(m)`

.

You might notice the number of soldiers equals to the position of the first civilian. You do not need to compute the costly summation.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
vector<int> kWeakestRows(vector<vector<int>>& mat, int k) {
using myPair = pair<int,int>;
vector<myPair> v;
for (int i = 0; i < mat.size(); i++) {
int num = find(mat[i].begin(), mat[i].end(), 0) - mat[i].begin();
v.push_back(make_pair(num, i));
}
sort(v.begin(), v.end());
vector<int> result;
for (int i = 0; i < k; i++) {
result.push_back(v[i].second);
}
return result;
}
void printResult(vector<int>& result) {
cout << "[";
for (int a : result) {
cout << a << ",";
}
cout << "]\n";
}
int main() {
vector<vector<int>> mat{{1,1,0,0,0},
{1,1,1,1,0},
{1,0,0,0,0},
{1,1,0,0,0},
{1,1,1,1,1}};
auto result = kWeakestRows(mat, 3);
printResult(result);
mat = {{1,0,0,0},
{1,1,1,1},
{1,0,0,0},
{1,0,0,0}};
result = kWeakestRows(mat, 2);
printResult(result);
}
```

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

- Runtime:
`O(mn)`

, where`m = mat.length, n = mat[i].length`

. - Extra space:
`O(m)`

.

The values in a row are sorted (first `1`

's then `0`

's). You can perform a binary search on it to reduce the runtime of the searching to `O(logn)`

using `std::lower_bound()`

.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
vector<int> kWeakestRows(vector<vector<int>>& mat, int k) {
using myPair = pair<int,int>;
vector<myPair> v;
for (int i = 0; i < mat.size(); i++) {
int num = lower_bound(mat[i].begin(), mat[i].end(), 0, greater()) - mat[i].begin();
v.push_back(make_pair(num, i));
}
sort(v.begin(), v.end());
vector<int> result;
for (int i = 0; i < k; i++) {
result.push_back(v[i].second);
}
return result;
}
void printResult(vector<int>& result) {
cout << "[";
for (int a : result) {
cout << a << ",";
}
cout << "]\n";
}
int main() {
vector<vector<int>> mat{{1,1,0,0,0},
{1,1,1,1,0},
{1,0,0,0,0},
{1,1,0,0,0},
{1,1,1,1,1}};
auto result = kWeakestRows(mat, 3);
printResult(result);
mat = {{1,0,0,0},
{1,1,1,1},
{1,0,0,0},
{1,0,0,0}};
result = kWeakestRows(mat, 2);
printResult(result);
}
```

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

- Runtime:
`O(mlogn)`

, where`m = mat.length, n = mat[i].length`

. - Extra space:
`O(m)`

.

Given two strings `s`

and `t`

, return `true`

if `s`

is a subsequence of `t`

, or `false`

otherwise.

A subsequence of a string is a new string that is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (i.e., `"ace"`

is a subsequence of `"abcde"`

while `"aec"`

is not).

```
Input: s = "abc", t = "ahbgdc"
Output: true
```

```
Input: s = "axc", t = "ahbgdc"
Output: false
```

`0 <= s.length <= 100`

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

.`s`

and`t`

consist only of lowercase English letters.

**Follow up**: Suppose there are lots of incoming `s`

, say `s1`

, `s2`

, ..., `sk`

where `k >= 10^9`

, and you want to check one by one to see if `t`

has its subsequence. In this scenario, how would you change your code?

For each character of `s`

, find if it exists in `t`

. If not, return `false`

.

Otherwise, continue with the next character of `s`

and the finding starting from the position after the last found one.

```
#include <iostream>
using namespace std;
bool isSubsequence(string s, string t) {
int i = -1;
for (char c : s) {
i++;
while (i < t.length() && t[i] != c) {
i++;
}
if (i >= t.length()){
return false;
}
}
return true;
}
int main() {
cout << isSubsequence("abc", "ahbgdc") << endl;
cout << isSubsequence("axc", "ahbgdc") << endl;
cout << isSubsequence("aaaa", "bbaaa") << endl;
}
```

```
Output:
1
0
0
```

- Runtime:
`O(N)`

, where`N = t.length`

. - Extra space:
`O(1)`

.

Suppose there are lots of incoming `s`

, say `s1, s2, ..., sk`

.

- If some is a subsequence of
`t`

then return`true`

. - If none of them satisfies, return
`false`

.

```
#include <iostream>
#include <vector>
using namespace std;
bool isSubsequence(string s, string t) {
int i = -1;
for (char c : s) {
i++;
while (i < t.length() && t[i] != c) {
i++;
}
if (i >= t.length()){
return false;
}
}
return true;
}
bool hasSubsequence(vector<string>& strings, string t) {
for (string& s : strings) {
if (isSubsequence(s, t)) {
return true;
}
}
return false;
}
int main() {
vector<string> strings{"abc", "axc", "aaaa"};
cout << hasSubsequence(strings, "ahbgdc") << endl;
strings = {"abcd", "axc", "aaaa"};
cout << hasSubsequence(strings, "ahbgdc") << endl;
}
```

```
Output:
1
0
```

- Runtime:
`O(kN)`

, where`k = strings.length`

and`N = t.length`

. - Extra space:
`O(1)`

.

Given an array of integers `nums`

which is sorted in ascending order, and an integer `target`

, write a function to search `target`

in `nums`

. If `target`

exists, then return its index. Otherwise, return `-1`

.

You must write an algorithm with `O(log n)`

runtime complexity.

```
Input: nums = [-1,0,3,5,9,12], target = 9
Output: 4
Explanation: 9 exists in nums and its index is 4
```

```
Input: nums = [-1,0,3,5,9,12], target = 2
Output: -1
Explanation: 2 does not exist in nums so return -1
```

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

.`-10^4 < nums[i], target < 10^4`

.- All the integers in
`nums`

are unique. `nums`

is sorted in ascending order.

Since `nums`

is sorted in ascending order you can divide it into subparts to find the `target`

. You can use the middle elements of `nums`

to divide the subparts. `target`

might equal to that element, on the left subpart or in the right subpart.

```
#include <vector>
#include <iostream>
using namespace std;
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
int main() {
vector<int> nums{-1,0,3,5,9,12};
cout << search(nums, 9) << endl;
cout << search(nums, 2) << endl;
}
```

```
Output:
4
-1
```

- Runtime:
`O(logN)`

where`N = nums.length`

. - Extra space:
`O(1)`

.

`mid`

is actually`(right + left) / 2`

. But`(right + left)`

might be too big to be overflow before the division. To avoid that overflow you can rewrite the expression to`mid = left + (right - left) / 2`

.

A company is planning to interview `2n`

people. Given the array costs where `costs[i] = [aCost_i, bCost_i]`

, the cost of flying the `i-th`

person to city `a`

is `aCost_i`

, and the cost of flying the `i-th`

person to city `b`

is `bCost_i`

.

Return the minimum cost to fly every person to a city such that exactly `n`

people arrive in each city.

```
Input: costs = [[10,20],[30,200],[400,50],[30,20]].
Output: 110.
Explanation:
The first person goes to city A for a cost of 10.
The second person goes to city A for a cost of 30.
The third person goes to city B for a cost of 50.
The fourth person goes to city B for a cost of 20.
The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city.
```

```
Input: costs = [[259,770],[448,54],[926,667],[184,139],[840,118],[577,469]]
Output: 1859.
Explanation: 1859 = 259 + 54 + 667 + 184 + 118 + 577.
```

```
Input: costs = [[515,563],[451,713],[537,709],[343,819],[855,779],[457,60],[650,359],[631,42]]
Output: 3086.
Explanation: 3086 = 515 + 451 + 537 + 343 + 779 + 60 + 359 + 42.
```

`2 * n == costs.length`

.`2 <= costs.length <= 100`

.`costs.length`

is even.`1 <= aCost_i, bCost_i <= 1000`

.

Every candidate should fly to the city with a lower cost. But the problem requires they must share their appearance equally between the two cities. It means somebody might have to fly with a higher cost.

Because the company considers only the total cost sum, you should choose the ones that sacrifice minimal cost for their flight to make them happy to switch.

For `costs = [[259,770],[448,54],[926,667],[184,139],[840,118],[577,469]]`

:

- If everyone can fly with a lower cost, only the first person flies to city
`a`

, the others fly to city`b`

. - But with the problem's constraint, some have to fly to city
`a`

. The ones that have the least sacrifices in cost are the fourth one (`184 - 139 = 45`

) and the last one (`577 - 469 = 108`

). You can say the company only has to pay`45 + 108 = 153`

(dollars) more for its optimal scheduling. - The final cost is
`259 + 54 + 667 + 184 + 118 + 577 = 1859`

.

You can generalize the idea of sacrifice for all candidates.

For instance in Example 2, you might say the first one "sacrifices" `259 - 770 = -511`

(dollars) as well because you will choose the ones with the least sacrifices anyway.

```
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int twoCitySchedCost(vector<vector<int>>& costs) {
// sort on the sacrifices in cost
sort(costs.begin(), costs.end(), [](const vector<int>& a, const vector<int>& b){
return a[0] - a[1] < b[0] - b[1];
});
int cost = 0;
for (int i = 0; i < costs.size() / 2; i++) { // first n person
cost += costs[i][0];
}
for (int i = costs.size() / 2; i < costs.size(); i++) {
cost += costs[i][1];
}
return cost;
}
int main() {
vector<vector<int>> costs{{10,20},{30,200},{400,50},{30,20}};
cout << twoCitySchedCost(costs) << endl;
costs = {{259,770},{448,54},{926,667},{184,139},{840,118},{577,469}};
cout << twoCitySchedCost(costs) << endl;
}
```

```
Output:
110
1859
```

- Runtime:
`O(NlogN)`

, where`N = costs.length`

. - Extra space:
`O(1)`

.

You are given an array `people`

where `people[i]`

is the weight of the `i-th`

person, and an infinite number of boats where each boat can carry a maximum weight of `limit`

. Each boat carries at most two people at the same time, provided the sum of the weight of those people is at most `limit`

.

Return the minimum number of boats to carry every given person.

```
Input: people = [1,2], limit = 3
Output: 1
Explanation: 1 boat (1, 2)
```

```
Input: people = [3,2,2,1], limit = 3
Output: 3
Explanation: 3 boats (1, 2), (2) and (3)
```

```
Input: people = [3,5,3,4], limit = 5
Output: 4
Explanation: 4 boats (3), (3), (4), (5)
```

`1 <= people.length <= 5 * 10^4`

.`1 <= people[i] <= limit <= 3 * 10^4`

.

For each boat pick the heaviest person first. The remaining weight on that boat might be not enough for anyone else. Otherwise, let the lightest one go as well.

For `people = [3,2,2,1]`

and `limit = 3`

:

- The heaviest one is
`3`

. He reaches the`limit`

. This boat can carry only him. - The next heavy one is
`2`

. This boat may carry one more with at most`1`

in weight. The lightest one ( weight`1`

) satisfies that. They are on this same boat. - The last boat carries the last person with weight
`2`

.

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

```
Output:
1
3
4
```

- Runtime:
`O(NlogN)`

, where`N = people.length`

. - Extra space:
`O(1)`

.

There is a broken calculator that has the integer `startValue`

on its display initially. In one operation, you can only either:

- multiply the number on display by
`2`

, or - subtract
`1`

from the number on display.

Given two integers `startValue`

and `target`

, return the minimum number of operations needed to display `target`

on the calculator.

```
Input: startValue = 2, target = 3
Output: 2
Explanation: Use double operation and then decrement operation {2 -> 4 -> 3}.
```

```
Input: startValue = 5, target = 8
Output: 2
Explanation: Use decrement and then double {5 -> 4 -> 8}.
```

```
Input: startValue = 3, target = 10
Output: 3
Explanation: Use double, decrement and double {3 -> 6 -> 5 -> 10}.
```

`1 <= x, y <= 10^9`

.

`target`

It is no doubt that if `startValue >= target`

, you have to go for subtraction exact `startValue - target`

times.

Let us consider only the case `startValue < target`

like the Examples above.
The optimal result of the Examples are:

- Example 1:
`{2 -> 4 -> 3}`

. - Example 2:
`{5 -> 4 -> 8}`

. - Example 3:
`{3 -> 6 -> 5 -> 10}`

.

What is the pattern?

It is hard to see what is the pattern if you read the chains from left to right. Why `2 -> 4`

in Example 1, but `5 -> 4`

in Example 2? Too smart!

What if you read it from right to left?

Here is the pattern:

- If
`target`

is even, its previous value is its half (Example 2, 3). - If
`target`

is odd, its previous value is incremental by one (Example 1).

So you can go backward starting from the `target`

instead of starting from the `startValue`

.

```
#include <iostream>
int brokenCalc(int startValue, int target) {
if (startValue >= target) {
return startValue - target;
}
if (target % 2 == 0) {
return 1 + brokenCalc(startValue, target/2);
}
return 1 + brokenCalc(startValue, target + 1);
}
int main() {
std::cout << brokenCalc(2,3) << std::endl;
std::cout << brokenCalc(3,10) << std::endl;
std::cout << brokenCalc(5,8) << std::endl;
std::cout << brokenCalc(1024,1) << std::endl;
std::cout << brokenCalc(1,1000000000) << std::endl;
}
```

```
Output:
2
3
2
1023
39
```

- Runtime:
`O(logN)`

, where`N = target`

. - Extra space:
`O(1)`

.

The numeric value of a lowercase character is defined as its position (`1-indexed`

) in the alphabet, so the numeric value of `a`

is `1`

, the numeric value of `b`

is `2`

, the numeric value of `c`

is `3`

, and so on.

The numeric value of a string consisting of lowercase characters is defined as the sum of its characters' numeric values. For example, the numeric value of the string `"abe"`

is equal to `1 + 2 + 5 = 8`

.

You are given two integers `n`

and `k`

. Return the lexicographically smallest string with length equal to `n`

and numeric value equal to `k`

.

Note that a string `x`

is lexicographically smaller than string `y`

if `x`

comes before `y`

in dictionary order, that is, either `x`

is a prefix of `y`

, or if `i`

is the first position such that `x[i] != y[i]`

, then `x[i]`

comes before `y[i]`

in alphabetic order.

```
Input: n = 3, k = 27
Output: "aay"
Explanation: The numeric value of the string is 1 + 1 + 25 = 27, and it is the smallest string with such a value and length equal to 3.
```

```
Input: n = 5, k = 73
Output: "aaszz"
```

`1 <= n <= 10^5`

.`n <= k <= 26 * n`

.

Construct the result from scratch, from left to right.

For each position, add the smallest possible character.

Let us call the resulting string `s`

.
To compute the smallest possible character for `s[i]`

, you can assume the remaining letters after `s[i]`

are all `z`

.

For `n = 3, k = 27`

.

- Assume
`s = "?zz"`

. Then`k - "zz" = 27 - 52 = -25 <= 'a'`

. So`s[0]`

can be`'a'`

. - Assume
`s = "a?z"`

. Then`k - "az" = 27 - 27 = 0 <= 'a'`

. So`s[1]`

can be`'a'`

. - Now
`s = "aa?"`

and`k - "aa" = 27 - 2 = 25 = 'y'`

. So`s[2] = 'y'`

. `s = "aay"`

.

```
#include <iostream>
using namespace std;
string getSmallestString(int n, int k) {
string s;
while (n > 0) {
int i = k - 26*(n - 1); // assume remain letters are all 'z'
char c = i <= 1 ? 'a' : 'a' + i - 1;
s += c;
k -= c - 'a' + 1;
n--;
}
return s;
}
int main() {
cout << getSmallestString(3, 27) << endl;
cout << getSmallestString(5, 73) << endl;
}
```

```
Output:
aay
aaszz
```

- Runtime:
`O(n)`

. - Extra space:
`O(1)`

.

`"aa...a"`

You can do the other way around by starting from `s = "aa...a"`

and adjusting each letter `'a'`

from right to left to be the biggest possible.

For `n = 5`

and `k = 73`

:

- Starting with
`s = "aaaaa"`

. `k`

becomes`73 - "aaaaa" = 68`

, which is big enough to make the last`'a'`

becomes`'z'`

:`s = "aaaaz"`

.`k`

becomes`73 - "aaaaz" = 43`

, which is big enough to make the next`'a'`

becomes`'z'`

:`s = "aaazz"`

.`k`

becomes`73 - "aaazz" = 18`

, which make the next`'a'`

becomes`'s'`

:`s = "aaszz"`

.`s = "aaszz"`

.

```
#include <iostream>
#include <string>
using namespace std;
string getSmallestString(int n, int k) {
string s(n, 'a');
k -= n;
while (k > 0 && n > 0) {
if (k > 25) {
s[n - 1] = 'z';
k -= 25;
n--;
} else {
s[n - 1] = 'a' + k;
break;
}
}
return s;
}
int main() {
cout << getSmallestString(3, 27) << endl;
cout << getSmallestString(5, 73) << endl;
}
```

```
Output:
aay
aaszz
```

- Runtime:
`O(n)`

. But it is faster than Solution 1 since there are fewer operations, especially there is no multiplication. - Extra space:
`O(1)`

.

You are given a string `s`

. We want to partition the string into as many parts as possible so that each letter appears in at most one part.

Note that the partition is done so that after concatenating all the parts in order, the resultant string should be `s`

.

Return a list of integers representing the size of these parts.

```
Input: s = "ababcbacadefegdehijhklij"
Output: [9,7,8]
Explanation:
The partition is "ababcbaca", "defegde", "hijhklij".
This is a partition so that each letter appears in at most one part.
A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits s into fewer parts.
```

```
Input: s = "eccbbbbdec"
Output: [10]
```

`1 <= s.length <= 500`

.`s`

consists of lowercase English letters.

For each character of `s`

, find the last occurrence to identify the minimal part. Extend this part if some other characters inside it have the last occurrence exceeding the part.

For `s = "ababcbacadefegdehijhklij"`

:

- The first character
`'a'`

gives you its minimal part`"ababcbaca"`

. No character inside this part has the last occurrence exceeds it. - The next character
`'d'`

gives you its minimal part`"defegd"`

. But the last occurrence of`'e'`

inside this part exceeds it. The part becomes`"defegde"`

. - The next character
`'h'`

gives you its minimal part`"hijh"`

. But the last occurrence of`'j'`

exceeds it. The part becomes`"hijhklij"`

. End.

```
#include <vector>
#include <string>
#include <iostream>
using namespace std;
vector<int> partitionLabels(string s) {
vector<int> result;
int start = 0;
while (start < s.length()) {
auto lastPos = s.rfind(s[start]);
for (int j = start; j < lastPos; j++) {
lastPos = max(lastPos, s.rfind(s[j]));
}
result.push_back(lastPos - start + 1);
start = lastPos + 1;
}
return result;
}
void printResult(vector<int>& result) {
cout << "[";
for (int a : result) {
cout << a << ",";
}
cout << "]\n";
}
int main() {
auto result = partitionLabels("ababcbacadefegdehijhklij");
printResult(result);
result = partitionLabels("eccbbbbdec");
printResult(result);
}
```

```
Output:
[9,7,8,]
[10,]
```

- Runtime:
`O(N^2)`

, where`N = s.length`

. - Extra space:
`O(1)`

.

In the solution above, the searching `s.rfind(c)`

is repeated if character `c`

appears multiple times in `s`

. You could store those searching before computing the parts to avoid the refinding.

```
#include <vector>
#include <string>
#include <iostream>
#include <unordered_map>
using namespace std;
vector<int> partitionLabels(string s) {
vector<int> result;
unordered_map<char, int> lastPos;
for (int i = 0; i < s.length(); i++) {
lastPos[s[i]] = i;
}
int start = 0;
while (start < s.length()) {
auto curLastPos = lastPos[s[start]];
for (int j = start + 1; j < curLastPos; j++) {
curLastPos = max(curLastPos, lastPos[s[j]]);
}
result.push_back(curLastPos - start + 1);
start = curLastPos + 1;
}
return result;
}
void printResult(vector<int>& result) {
cout << "[";
for (int a : result) {
cout << a << ",";
}
cout << "]\n";
}
int main() {
auto result = partitionLabels("ababcbacadefegdehijhklij");
printResult(result);
result = partitionLabels("eccbbbbdec");
printResult(result);
}
```

```
Output:
[9,7,8,]
[10,]
```

- Runtime:
`O(N)`

, where`N = s.length`

. - Extra space:
`O(1)`

. Though a map seems to require`O(N)`

, in this problem the map requires only 26`int`

's for the lowercase letters. It can be considered`O(1)`

.

In a row of dominoes, `tops[i]`

and `bottoms[i]`

represent the top and bottom halves of the `i-th`

domino. (A domino is a tile with two numbers from 1 to 6 - one on each half of the tile.)

We may rotate the `i-th`

domino, so that `tops[i]`

and `bottoms[i]`

swap values.

Return the minimum number of rotations so that all the values in `tops`

are the same, or all the values in `bottoms`

are the same.

If it cannot be done, return `-1`

.

```
Input: tops = [2,1,2,4,2,2], bottoms = [5,2,6,2,3,2]
Output: 2
Explanation:
The first figure represents the dominoes as given by tops and bottoms: before we do any rotations.
If we rotate the second and fourth dominoes, we can make every value in the top row equal to 2, as indicated by the second figure.
```

```
Input: tops = [3,5,1,2,3], bottoms = [3,6,3,3,4]
Output: -1
Explanation:
In this case, it is not possible to rotate the dominoes to make one row of values equal.
```

`2 <= tops.length <= 2 * 10^4`

.`bottoms.length == tops.length`

.`1 <= tops[i], bottoms[i] <= 6`

.

"All the values in `tops`

are the same" means they are equal to `tops[0]`

.

Similarly, "all the values in `botoms`

are the same" means they are equal to `bottoms[0]`

.

You just need to compute the result for `tops[0]`

and for `bottoms[0]`

and compare them for the final result.

```
#include <vector>
#include <iostream>
using namespace std;
int minDominoRotations(vector<int>& tops, vector<int>& bottoms) {
int topCount = 1;
int bottomCount = 0;
for (int i = 1; i < tops.size(); i++) {
if (tops[i] != tops[0] && bottoms[i] != tops[0]) {
tops[0] = 0;
break;
}
topCount += tops[i] == tops[0];
bottomCount += bottoms[i] == tops[0];
}
int topResult = tops[0] ? tops.size() - max(topCount, bottomCount) : -1;
if (topResult == 0) {
return 0;
}
bottomCount = 1;
topCount = 0;
for (int i = 1; i < bottoms.size(); i++) {
if (tops[i] != bottoms[0] && bottoms[i] != bottoms[0]) {
bottoms[0] = 0;
break;
}
topCount += tops[i] == bottoms[0];
bottomCount += bottoms[i] == bottoms[0];
}
int bottomResult = bottoms[0] ? bottoms.size() - max(topCount, bottomCount) : -1;
return (topResult >= 0 && bottomResult >= 0) ?
min(topResult, bottomResult) : max(topResult, bottomResult);
}
int main() {
vector<int> tops{2,1,2,4,2,2};
vector<int> bottoms{5,2,6,2,3,2};
cout << minDominoRotations(tops, bottoms) << endl;
tops = {1,2,1,1,1,2,2,2};
bottoms = {2,1,2,2,2,2,2,2};
cout << minDominoRotations(tops, bottoms) << endl;
}
```

```
Output:
2
1
```

- Runtime:
`O(N)`

, where`N = tops.length`

. - Extra space:
`O(1)`

.

- To save one or two boolean variables for flagging whether the swapping happens, you can use/modify the value of the fixed values that you choose to compare with the others. Here they are
`tops[0]`

and`bottoms[0]`

. - The value of a boolean expression, e.g.
`tops[i] == tops[0]`

is casted to`0`

(`false`

) or`1`

(`true`

) when it is used in an`int`

expression. So you can write`topCount += tops[i] == tops[0]`

.

You are given an `m x n`

integer grid `accounts`

where `accounts[i][j]`

is the amount of money the `i-th`

customer has in the `j-th`

bank. Return the wealth that the richest customer has.

A customer's **wealth** is the amount of money they have in all their bank accounts. The richest customer is the customer that has the maximum wealth.

```
Input: accounts = [[1,2,3],[3,2,1]]
Output: 6
Explanation:
1st customer has wealth = 1 + 2 + 3 = 6
2nd customer has wealth = 3 + 2 + 1 = 6
Both customers are considered the richest with a wealth of 6 each, so return 6.
```

```
Input: accounts = [[1,5],[7,3],[3,5]]
Output: 10
Explanation:
1st customer has wealth = 6
2nd customer has wealth = 10
3rd customer has wealth = 8
The 2nd customer is the richest with a wealth of 10.
```

```
Input: accounts = [[2,8,7],[7,1,3],[1,9,5]]
Output: 17
```

`m == accounts.length`

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

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

.`1 <= accounts[i][j] <= 100`

.

Compute the wealth for each account to determine who is the richest.

```
#include <vector>
#include <iostream>
using namespace std;
int maximumWealth(vector<vector<int>>& accounts) {
int maxWealth = 0;
for (int i = 0; i < accounts.size(); i++) {
int w = 0;
for (auto& money : accounts[i]) {
w += money;
}
maxWealth = max(maxWealth, w);
}
return maxWealth;
}
int main() {
vector<vector<int>> accounts{{1,2,3},{3,2,1}};
cout << maximumWealth(accounts) << endl;
accounts = {{1,5},{7,3},{3,5}};
cout << maximumWealth(accounts) << endl;
accounts = {{2,8,7},{7,1,3},{1,9,5}};
cout << maximumWealth(accounts) << endl;
}
```

```
Output:
6
10
17
```

- Runtime
`O(m*n)`

, where`m = accounts.length`

,`n == accounts[i].length`

. - Extra space:
`O(1)`

.

`std::accumulate()`

Computing the sum of a vector `v`

is a very common task. There are many ways to achieve it. One way is using function `std::accumulate()`

.

```
#include <vector>
#include <iostream>
#include <numeric>
using namespace std;
int maximumWealth(vector<vector<int>>& accounts) {
int maxWealth = 0;
for (auto& account : accounts) {
maxWealth = max(maxWealth, accumulate(account.begin(), account.end(), 0));
}
return maxWealth;
}
int main() {
vector<vector<int>> accounts{{1,2,3},{3,2,1}};
cout << maximumWealth(accounts) << endl;
accounts = {{1,5},{7,3},{3,5}};
cout << maximumWealth(accounts) << endl;
accounts = {{2,8,7},{7,1,3},{1,9,5}};
cout << maximumWealth(accounts) << endl;
}
```

```
Output:
6
10
17
```

- Runtime
`O(m*n)`

, where`m = accounts.length`

,`n == accounts[i].length`

. - Extra space:
`O(1)`

.

`std::max_element()`

Depending on your application, sometimes you might want to store the `wealths`

of all customers. Computing the maximum element of a vector is also a very common task, which can be performed by the function called `std::max_element()`

.

```
#include <vector>
#include <iostream>
#include <numeric>
#include <algorithm>
using namespace std;
int maximumWealth(vector<vector<int>>& accounts) {
vector<int> wealths;
for (auto& account : accounts) {
wealths.push_back(accumulate(account.begin(), account.end(), 0));
}
return *max_element(wealths.begin(), wealths.end());
}
int main() {
vector<vector<int>> accounts{{1,2,3},{3,2,1}};
cout << maximumWealth(accounts) << endl;
accounts = {{1,5},{7,3},{3,5}};
cout << maximumWealth(accounts) << endl;
accounts = {{2,8,7},{7,1,3},{1,9,5}};
cout << maximumWealth(accounts) << endl;
}
```

```
Output:
6
10
17
```

- Runtime
`O(m*n)`

, where`m = accounts.length`

,`n == accounts[i].length`

. - Extra space:
`O(1)`

.

Given four integer arrays `nums1`

, `nums2`

, `nums3`

, and `nums4`

all of length `n`

, return the number of tuples `(i, j, k, l)`

such that:

`0 <= i, j, k, l < n`

.`nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0`

.

```
Input: nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2].
Output: 2.
Explanation:
The two tuples are:
1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0.
2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0.
```

```
Input: nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0].
Output: 1.
```

`nums1.length = nums2.length = nums3.length = nums4.length = n`

.`1 <= n <= 200`

.`-2^28 <= nums1[i], nums2[i], nums3[i], nums4[i] <= 2^28`

.

```
#include <iostream>
#include <vector>
using namespace std;
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int count = 0;
for (auto& n1 : nums1) {
for (auto& n2 : nums2) {
for (auto& n3 : nums3) {
for (auto& n4 : nums4) {
if (n1 + n2 + n3 + n4 == 0) {
count++;
}
}
}
}
}
return count;
}
int main() {
vector<int> nums1, nums2, nums3, nums4;
nums1 = {1, 2};
nums2 = {-2, -1};
nums3 = {-1, 2};
nums4 = {0, 2};
cout << fourSumCount(nums1, nums2, nums3, nums4) << endl;
nums1 = {0};
nums2 = {0};
nums3 = {0};
nums4 = {0};
cout << fourSumCount(nums1, nums2, nums3, nums4) << endl;
}
```

```
Output:
2
1
```

- Runtime:
`O(n^4)`

. - Extra memory:
`O(1)`

.

Rewriting `nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0`

as `nums1[i] + nums2[j] == 0 - nums3[k] - nums4[l]`

you could reduce the runtime complexity of the solution above from `O(n^4)`

to `O(n^2)`

by storing the sum `nums1[i] + nums2[j]`

in a map.

```
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int count = 0;
unordered_map<int, int> sumTwo;
for (auto& n1 : nums1) {
for (auto& n2 : nums2) {
sumTwo[n1 + n2]++;
}
}
for (auto& n3 : nums3) {
for (auto& n4 : nums4) {
auto it = sumTwo.find(0 - n3 - n4);
if (it != sumTwo.end()) {
count += it->second;
}
}
}
return count;
}
int main() {
vector<int> nums1, nums2, nums3, nums4;
nums1 = {1, 2};
nums2 = {-2, -1};
nums3 = {-1, 2};
nums4 = {0, 2};
cout << fourSumCount(nums1, nums2, nums3, nums4) << endl;
nums1 = {0};
nums2 = {0};
nums3 = {0};
nums4 = {0};
cout << fourSumCount(nums1, nums2, nums3, nums4) << endl;
}
```

```
Output:
2
1
```

- Runtime:
`O(n^2)`

. - Extra memory:
`O(n^2)`

.

Given a balanced parentheses string `s`

, return the score of the string.

The score of a balanced parentheses string is based on the following rule:

`"()"`

has score`1`

.`AB`

has score`A + B`

, where`A`

and`B`

are balanced parentheses strings.`(A)`

has score`2 * A`

, where`A`

is a balanced parentheses string.

```
Input: s = "()"
Output: 1
```

```
Input: s = "(())"
Output: 2
```

```
Input: s = "()()"
Output: 2
```

`2 <= s.length <= 50`

.`s`

consists of only`'('`

and`')'`

.`s`

is a balanced parentheses string.

Because `s`

is a balanced parentheses string, it can be split into sub balanced parentheses ones. So you can follow the scoring rule to perform the recursive algorithm.

```
#include <string>
#include <iostream>
using namespace std;
int scoreOfParentheses(string s) {
if (s == "()") {
return 1;
}
// find the sub balanced parentheses A if s = AB
int i = 1; // s always starts with '(', now starting i with the next one
int balance = 1;
while (i < s.length() && balance != 0 ) {
balance = (s[i] == '(') ? balance + 1 : balance - 1;
i++;
}
if (i < s.length()) { // s = AB
return scoreOfParentheses(s.substr(0, i)) + scoreOfParentheses(s.substr(i));
}
// A = (C)
return 2*scoreOfParentheses(s.substr(1, s.length() - 2));
}
int main() {
cout << scoreOfParentheses("()") << endl;
cout << scoreOfParentheses("(())") << endl;
cout << scoreOfParentheses("()()") << endl;
cout << scoreOfParentheses("(()(()))") << endl;
}
```

```
Output:
1
2
2
6
```

- Runtime:
`O(N)`

, where`N = s.length`

. - Extra space:
`O(logN)`

due to the recursive.

Given two integer arrays `pushed`

and `popped`

each with distinct values, return `true`

if this could have been the result of a sequence of push and pop operations on an initially empty stack, or `false`

otherwise.

```
Input: pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
Output: true
Explanation: We might do the following sequence:
push(1), push(2), push(3), push(4),
pop() -> 4,
push(5),
pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
```

```
Input: pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
Output: false
Explanation: 1 cannot be popped before 2.
```

`1 <= pushed.length <= 1000`

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

.- All the elements of
`pushed`

are unique. `popped.length == pushed.length`

.`popped`

is a permutation of`pushed`

.

**Step 1.** Go through `pushed`

until the popping can be performed.

**Step 2.** Perform the popping by erasure as much as possible.

**Step 3.** Continue **Step 1** and **Step 2** until they cannot be performed anymore.

With `pushed = [1,2,3,4,5]`

and `popped = [4,5,3,2,1]`

:

- Go through
`pushed`

starting from`pushed.top = 1`

until`pushed.top = 4`

, when the popping can be performed because`4 == popped[0]`

. Only one popping can be performed. Erase (pop) that value,`pushed`

becomes`[1,2,3]`

. - Continue going through
`pushed`

,`pushed.top = 5`

, and the popping can be performed since`5 == popped[1]`

. Now the popping can be performed fully all values of`pushed`

and`popped`

. - End.

```
#include <vector>
#include <iostream>
using namespace std;
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
int i = 0;
int j = 0;
while (i < pushed.size()) {
// perform the popping by erasure as much as possible
while (i >= 0 && pushed[i] == popped[j]) {
pushed.erase(pushed.begin() + i);
i--;
j++;
}
i++;
}
return pushed.empty();
}
int main() {
vector<int> pushed{1,2,3,4,5};
vector<int> popped{4,5,3,2,1};
cout << validateStackSequences(pushed, popped) << endl;
pushed = {1,2,3,4,5};
popped = {4,3,5,1,2};
cout << validateStackSequences(pushed, popped) << endl;
pushed = {2,0,3,1};
popped = {3,1,0,2};
cout << validateStackSequences(pushed, popped) << endl;
}
```

```
Output:
1
0
1
```

- Runtime:
`O(NlogN)`

, where`N = pushed.length`

. Though the complexity of`vector::erase()`

is linear, the`pushed.size()`

is reduced whenever the popping happened. - Extra space:
`O(1)`

.

Popping by erasure reduced the length of `pushed`

. But using `vector::erase()`

like that might cost some runtime.

Remember that popping and pushing are performed on the top of `pushed`

. If a popping happened, a pushing right after that is simply a value reassignment on the top element.

```
#include <vector>
#include <iostream>
using namespace std;
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
int i = 0; // index of pushed's top
int j = 0;
for (int a : pushed) {
pushed[i++] = a; // (re)assign a to the top element
// perform the pop as much as possible
while (i > 0 && pushed[i - 1] == popped[j]) {
i--;
j++;
}
}
return i == 0;
}
int main() {
vector<int> pushed{1,2,3,4,5};
vector<int> popped{4,5,3,2,1};
cout << validateStackSequences(pushed, popped) << endl;
pushed = {1,2,3,4,5};
popped = {4,3,5,1,2};
cout << validateStackSequences(pushed, popped) << endl;
pushed = {2,0,3,1};
popped = {3,1,0,2};
cout << validateStackSequences(pushed, popped) << endl;
}
```

```
Output:
1
0
1
```

- Runtime:
`O(N)`

, where`N = pushed.length`

. - Extra space:
`O(1)`

.

- In the statement
`for (int a : pushed)`

, all values`a`

of the original`pushed`

were stored in a copy of`pushed`

. So you did not lose any of them.

Given a string s of `'('`

, `')'`

and lowercase English characters.

Your task is to remove the minimum number of parentheses ( `'('`

or `')'`

, in any positions) so that the resulting parentheses string is valid and return any valid string.

Formally, a parentheses string is valid if and only if:

- It is the empty string, contains only lowercase characters, or
- It can be written as
`AB`

(`A`

concatenated with`B`

), where`A`

and`B`

are valid strings, or - It can be written as
`(A)`

, where`A`

is a valid string.

```
Input: s = "lee(t(c)o)de)"
Output: "lee(t(c)o)de"
Explanation: "lee(t(co)de)" , "lee(t(c)ode)" would also be accepted.
```

```
Input: s = "a)b(c)d"
Output: "ab(c)d"
```

```
Input: s = "))(("
Output: ""
Explanation: An empty string is also valid.
```

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

.`s[i]`

is either`'('`

,`')'`

, or lowercase English letters.

- Construct the result from the valid characters of
`s`

. - You can use a stack to store the positions of the open brackets
`'('`

which can be canceled out by later closed ones`')'`

. - Any remaining
`'('`

are removed.

```
#include <iostream>
#include <stack>
using namespace std;
string minRemoveToMakeValid(string s) {
string result;
stack<int> pos;
for (char c: s) {
if (c == ')' && pos.empty() ) {
continue;
}
result += c;
if (c == '(') {
pos.push(result.length() - 1);
} else if (c == ')') {
pos.pop();
}
}
while (!pos.empty()) {
result.erase(result.begin() + pos.top());
pos.pop();
}
return result;
}
int main() {
cout << minRemoveToMakeValid("lee(t(c)o)de)") << endl;
cout << minRemoveToMakeValid("a)b(c)d") << endl;
cout << minRemoveToMakeValid("))((") << endl;
}
```

```
Output:
lee(t(c)o)de
ab(c)d
```

- Runtime:
`O(N)`

, where`N = s.length`

. - Extra space:
`O(N)`

.

If there are many `string::erase()`

are performed, the runtime would not be good since the complexity of this function is not constant.

One way to avoid it is constructing the new result from scratch skipping the marked characters.

```
#include <iostream>
#include <stack>
using namespace std;
string minRemoveToMakeValid(string s) {
{
stack<int> pos;
for (int i = 0; i < s.length(); i++) {
if (s[i] == ')' && pos.empty() ) {
s[i] = '0';
continue;
}
if (s[i] == '(') {
pos.push(i);
} else if (s[i] == ')') {
pos.pop();
}
}
while (!pos.empty()) {
s[pos.top()] = '0';
pos.pop();
}
}
string result;
for (char c : s) {
if (c != '0') {
result += c;
}
}
return result;
}
int main() {
cout << minRemoveToMakeValid("lee(t(c)o)de)") << endl;
cout << minRemoveToMakeValid("a)b(c)d") << endl;
cout << minRemoveToMakeValid("))((") << endl;
}
```

```
Output:
lee(t(c)o)de
ab(c)d
```

- Runtime:
`O(N)`

, where`N = s.length`

. - Extra space:
`O(N)`

.

- Since
`s`

contains only characters`'('`

,`')'`

or lowercase English letters, you can use any other one to mark the skipped characters. - You can scope a piece of code between the pair
`{ ... }`

to release some local memory (e.g. the stack`pos`

) because the variable is destroyed at the end of the scope.

Given a string `path`

, which is an absolute path (starting with a slash `'/'`

) to a file or directory in a Unix-style file system, convert it to the simplified canonical path.

In a Unix-style file system, a period `'.'`

refers to the current directory, a double period `'..'`

refers to the directory up a level, and any multiple consecutive slashes (i.e. `'//'`

) are treated as a single slash `'/'`

. For this problem, any other formats of periods such as `'...'`

are treated as file/directory names.

The canonical path should have the following format:

- The path starts with a single slash
`'/'`

. - Any two directories are separated by a single slash
`'/'`

. - The path does not end with a trailing
`'/'`

. - The path only contains the directories on the path from the root directory to the target file or directory (i.e., no period
`'.'`

or double period`'..'`

).

Return the simplified canonical path.

```
Input: path = "/home/"
Output: "/home"
Explanation: Note that there is no trailing slash after the last directory name.
```

```
Input: path = "/../"
Output: "/"
Explanation: Going one level up from the root directory is a no-op, as the root level is the highest level you can go.
```

```
Input: path = "/home//foo/"
Output: "/home/foo"
Explanation: In the canonical path, multiple consecutive slashes are replaced by a single one.
```

`1 <= path.length <= 3000`

.`path`

consists of English letters, digits, period`'.'`

, slash`'/'`

or`'_'`

.`path`

is a valid absolute Unix path.

`".."`

Following the format constraints, you can store the directories' names in a stack. With its LIFO property, the last directory can be removed whenever the directory `".."`

appears next.

```
#include <iostream>
#include <vector>
using namespace std;
string simplifyPath(string path) {
vector<string> s;
string dir;
for (char c : path) {
if (c != '/') {
dir += c;
continue;
}
if (dir == "..") {
if (!s.empty()) {
s.pop_back();
}
} else if (!dir.empty() && dir != ".") {
s.push_back(dir);
}
dir = "";
}
if (dir == "..") {
if (!s.empty()) {
s.pop_back();
}
} else if (!dir.empty() && dir != ".") {
s.push_back(dir);
}
dir = "";
for (auto d : s) {
dir += "/" + d;
}
return dir == "" ? "/" : dir;
}
int main() {
cout << simplifyPath("/home/") << endl;
cout << simplifyPath("/a/..") << endl;
cout << simplifyPath("/a//b////c/d//././/..") << endl;
cout << simplifyPath("/../") << endl;
cout << simplifyPath("/a/./b/../../c/") << endl;
}
```

```
Output:
/home
/
/a/b/c
/
/c
```

- Runtime:
`O(N)`

, where`N = path.length`

. - Extra space:
`O(N)`

.

As the property LIFO of a stack is used, you can use `std::stack`

to implement the algorithm. But here are the reasons you can use `std::vector`

for this purpose as well.

`std::vector`

also supports`pop_back()`

and`push_back()`

like a`std::stack`

.- It is clearer to go from the root directory to the children ones with
`std::vector`

when building the canonical path from the simplified directories at the end of the algorithm.

On the other hand, in the solution above, a piece of code is duplicated to add the last directory to the stack.

One way to avoid it is by adding a slash `'/'`

at the end of the `path`

to force it ends with `'/'`

. Then the duplicated code is handled inside the loop as well.

```
#include <iostream>
#include <vector>
using namespace std;
string simplifyPath(string path) {
path += "/";
vector<string> s;
string dir;
for (char c : path) {
if (c != '/') {
dir += c;
continue;
}
if (dir == "..") {
if (!s.empty()) {
s.pop_back();
}
} else if (!dir.empty() && dir != ".") {
s.push_back(dir);
}
dir = "";
}
dir = "";
for (auto d : s) {
dir += "/" + d;
}
return dir == "" ? "/" : dir;
}
int main() {
cout << simplifyPath("/home/") << endl;
cout << simplifyPath("/a/..") << endl;
cout << simplifyPath("/a//b////c/d//././/..") << endl;
cout << simplifyPath("/../") << endl;
cout << simplifyPath("/a/./b/../../c/") << endl;
}
```

```
Output:
/home
/
/a/b/c
/
/c
```

- Runtime:
`O(N)`

, where`N = path.length`

. - Extra space:
`O(N)`

.

You are given two strings `s`

and `t`

.

String `t`

is generated by random shuffling string `s`

and then adding one more letter at a random position.

Return the letter that was added to `t`

.

```
Input: s = "abcd", t = "abcde"
Output: "e"
Explanation: 'e' is the letter that was added.
```

```
Input: s = "", t = "y"
Output: "y"
```

`0 <= s.length <= 1000`

.`t.length == s.length + 1`

.`s`

and`t`

consist of lowercase English letters.

For each character in `t`

, check if it appears in `s`

. If so mark that character in `s`

as visited.

Let `s = "ababadbcb"`

and `t = "abadbbcbda"`

. When reaching character `'d'`

in `t`

you cannot find it in `s`

.

```
#include <iostream>
#include <vector>
using namespace std;
char findTheDifference(string s, string t) {
char a;
vector<bool> visited(s.size());
for (const char& c : t) {
int i = 0;
while (i < s.size()) {
if (!visited[i] && s[i] == c) {
visited[i] = true;
break;
}
i++;
}
if (i == s.size()) { // not found in s
a = c;
break;
}
}
return a;
}
int main() {
cout << findTheDifference("abcd", "bdcea") << endl;
cout << findTheDifference("", "y") << endl;
}
```

```
Output:
e
y
```

- Runtime:
`O(N*N)`

, where`N = s.length`

. - Extra space:
`O(N)`

.

Sort the strings and you can easily identify which character in `t`

was added.

Sorting `s = "ababadbcb"`

and `t = "abadbbcbda"`

you get `s = aaabbbbc`

and `t = aaabbbbcd`

. Every position of `t`

has the same character as in `s`

except the last one.

```
#include <iostream>
#include <algorithm>
using namespace std;
char findTheDifference(string s, string t) {
sort(s.begin(), s.end());
sort(t.begin(), t.end());
for (int i=0; i < s.size(); i++) {
if (s[i] != t[i]) {
return t[i];
}
}
return t.back();
}
int main() {
cout << findTheDifference("abcd", "abdce") << endl;
cout << findTheDifference("", "y") << endl;
}
```

```
Output:
e
y
```

- Runtime:
`O(NlogN)`

, where`N = s.length`

. - Extra space:
`O(1)`

.

Count the appearance of each character of the string `s`

then check which character of string `t`

was not counted.

Counting the appearances of the characters in `s = "ababadbcb"`

, you get:

```
count['a'] = 3;
count['b'] = 4;
count['c'] = 1;
```

Then with `t = "abadbbcbda"`

you can identify the character `'d'`

was not counted.

```
#include <iostream>
#include <unordered_map>
using namespace std;
char findTheDifference(string s, string t) {
unordered_map<char, int> m;
char a;
for (const char& c : s) {
m[c]++;
}
for (const char& c : t) {
m[c]--;
if (m[c] < 0) {
a = c;
break;
}
}
return a;
}
int main() {
cout << findTheDifference("abcd", "abdce") << endl;
cout << findTheDifference("", "y") << endl;
}
```

```
Output:
e
y
```

- Runtime:
`O(N)`

, where`N = s.length`

. - Extra space:
`O(N)`

.

Consider `s, t`

are multisets of characters. Then the result of the subtraction `t-s`

is what you want for this problem.

```
s = {'a', 'b', 'c', 'd'};
t = {'a', 'b', 'c', 'd', 'e'};
t - s = 'e'.
```

```
#include <iostream>
using namespace std;
char findTheDifference(string s, string t) {
int a = 0;
for (const char& c : t) {
a += c;
}
int b = 0;
for (const char& c : s) {
b += c;
}
return a - b;
}
int main() {
cout << findTheDifference("abcd", "abdce") << endl;
cout << findTheDifference("", "y") << endl;
}
```

```
Output:
e
y
```

Note that in this solution, you have applied the fact the value of a `char`

is an `int`

.

- Runtime:
`O(N)`

, where`N = s.length`

. - Extra space:
`O(1)`

.

`std::accumulate`

You can also use the function `std::accumulate`

from the Standard Library to compute the sums in the Solution 4.

```
#include <numeric>
#include <iostream>
using namespace std;
char findTheDifference(string s, string t) {
return accumulate(t.begin(), t.end(), 0) - accumulate(s.begin(), s.end(), 0);
}
int main() {
cout << findTheDifference("abcd", "abdce") << endl;
cout << findTheDifference("", "y") << endl;
}
```

```
Output:
e
y
```

- Runtime:
`O(N)`

, where`N = s.length`

. - Extra space:
`O(1)`

.

There is a lot of solutions to this simple problem.

In order to improve the performance of your solution, you might need to know how to make use of the information, the constraints of the problem and the features the programming language supports.

Finally, having some mathematical knowledge always helps. That you can see with the one-line solution of Solution 5, where Modern C++ meets Mathematics.

]]>Given the `head`

of a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Return the linked list sorted as well.

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

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

- The number of nodes in the list is in the range
`[0, 300]`

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

.- The list is guaranteed to be sorted in ascending order.

**Case 1**: There is no duplication on the current node (`nextNode.val != curNode.val`

).**Case 2**: A duplication happens (`nextNode.val == curNode.val`

).

```
#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* deleteDuplicates(ListNode* head) {
ListNode prehead;
ListNode* prevNode = &prehead;
ListNode* curNode = head;
prevNode->next = curNode;
while (curNode) {
int val = curNode->val;
ListNode* nextNode = curNode->next;
int count = 0;
while (nextNode && nextNode->val == val) {
nextNode = nextNode->next;
count++;
}
if (count == 0) {
prevNode = curNode;
curNode = nextNode;
} else {
curNode = nextNode;
prevNode->next = curNode;
}
}
return prehead.next;
}
void printResult(ListNode* head) {
std::cout << "[";
while (head) {
std::cout << head->val << ",";
head = head->next;
}
std::cout << "]\n";
}
int main() {
{
ListNode five(5);
ListNode four2(4, &five);
ListNode four1(4, &four2);
ListNode three3(3, &four1);
ListNode three2(3, &three3);
ListNode three1(3, &three2);
ListNode two(2, &three1);
ListNode one(1, &two);
printResult(deleteDuplicates(&one));
}
{
ListNode three(3);
ListNode two(2, &three);
ListNode one3(1, &two);
ListNode one2(1, &one3);
ListNode one1(1, &one2);
printResult(deleteDuplicates(&one1));
}
}
```

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

- Runtime:
`O(N)`

, where`N`

is the length of the linked list. - Extra space:
`O(1)`

.

`curNode = head`

is a corner case of any linked list problem because it has no`prevNode`

. To avoid rewriting code for this special case, you could introduce a dummy node before the`head`

(here is the`prehead`

).