CS 402 - Algorithms in Practice
Welcome to the class! I am excited to have you. Throughout this website, you’ll find all the relevant information needed for the course.
On this page, I’ll post important announcements, as well as a changelog. If you have any questions, please feel free to reach out to me.
Announcements
- [
November 22, 2025] Project 3 released. - [
November 13, 2025] Schedule updated with Final Exam time and date, and changes to last 2 weeks of schedule. - [
November 02, 2025] Midterm grades released on Gradescope. Miterm sample solutions posted to Piazza. - [
October 23, 2025] Project 2 released. - [
October 15, 2025] Fixed schedule. Added LeetCode from Class to website. - [
October 02, 2025] Various updates from class. See list below.- Schedule has been updated. Notable changes:
- Midterm Exam moved from Week 8 to Week 9.
- Project 2 to be released next week (Week 7).
- Time slots for the code presentations of Project 1 have been released. Please sign up via the link on Piazza. Also, Project 1 will be graded over the weekend.
- Blackboard will now be used for tracking grades for grades that cannot be tracked on Gradescope (e.g., in-class discussion, projects). As such, Blackboard has also been added to Important Links below and the Syllabus.
- Schedule has been updated. Notable changes:
- [
September 18, 2025] Schedule has been updated. - [
September 09, 2025] Project 1 released. - [
September 01, 2025] Office hours updated. - [
August 29, 2025] Added in-class report templates; see here. Gradescope updated to include the week 1 in-class report.
Important Info
Instructor: Alexander R. Block
Email: arblock [at] uic [dot] edu
Office Hours
- Thursdays, 2:00pm - 3:00pm (drop-in hours) or by appointment.
- Location: CDRLC 2404 (drop-in) or 4462 (by appointment only).
Course Modality and Schedule: In-person only, CDRLC 2406, 11:00am - 12:15pm Central Time, Tuesday & Thursday.
Student Guide for CDRLC: Google Doc
Important Links
Changelog
- [
August 26, 2025] Announcements updated. Typos fixed. - [
August 24, 2025] Website available.
Syllabus
Instructor and Course Details
Instructor: Alexander R. Block
Email: arblock [at] uic [dot] edu
Drop-in Office Hours
- Thursdays, 2:00pm - 3:00pm (drop-in hours) or by appointment.
- Location: CDLRC 2404 (drop-in) or 4462 (appointment only).
Course Modality and Schedule: In-person only, CDLRC 2406, 11:00am - 12:15pm, Tuesday & Thursday.
Gradescope: https://www.gradescope.com/courses/1097809
Piazza: https://piazza.com/uic/fall2025/cs402
Course Announcements
Course information will primarily be conveyed using this website (see here) and Piazza. Course discussion will happen on Piazza. All course assignments and grades will be collected and returned through Gradescope. I will also send email notifications to the class with announcements.
You are responsible for checking this website and emails for any and all updates and information regarding the course, including homework assignments and schedule changes. You are also responsible for keeping up to date on Piazza for any corrections and/or clarifications regarding assignments, or other important information.
Communication Expectations
Students are responsible for all information instructors send to your UIC email. Faculty messages should be regularly monitored and read in a timely fashion.
Please use Piazza private messages shared with the instructors (not just the professor or TA by name) if you wish to communicate with us directly. Please only use email for something that explicitly should be kept private only to that person.
Please email me if you face an unexpected situation that may impede your attendance, participation in class and exam sessions, or timely completion of assignments.
Course Information
CS 402 is a joint undergrad/graduate level course. The course is intended to be an applied follow-up course to CS 401. From the UIC course catalogue:
Design, implementation and presentation of algorithms and data structures emphasizing dynamic programming and both exact and heuristic approaches to NP-hard problems; problem solving sessions, programming projects and presentations.
Course Structure. This course will emphasize your skills as a CS student. Crucial to this, in my view, are the following skills:
- Designing and implementing algorithms/data structures to solve problems;
- Presenting these designs and implemenetations to others; and
- Continual improvement of skills.
As such, the aim of the course structure is to help you with these three skills. There will be an emphasis on practice of all of these skills. In order to achieve this, lectures will be sparse and I will try to only present reviews of concepts needed to help solve the problems that will be given in-class and for projects. In my opinion (and many others), students learn best by practicing, practicing, practicing!
Roughly speaking, we will divide up our in-class time as follows.
- Some brief review and/or introduction of materials/problems for the current section.
- Ample in-class time to attempt problems and understand materials.
- Reserved time for in-class presentations of the problems.
For in-class assignments, you will not be evaluated on whether or not you get a solution correctly the first time, but rather how you approach solving a problem, how well you explain and justify your approach and present it to others, and how well you improve over the course of this class. Your soft skills as a computer scientist are just as important as the hard skills (i.e., desigining and implementing), and I will be evaluating you on all such skills and looking for improvement. However, all projects and exams in this course will expect you to find the correct solution to the best of your ability.
You will be allowed to work individually or in groups during our in-class sessions, as well as for projects. It is highly encouraged to work in groups of 2-3 people to help build on each other’s skills. Note that it is easy for an instructor to tell if a single person in a group is doing all the work (or one of three in a larger group is doing no work). All exams will be individual.
Prerequisites: CS 401.
Brief list of topics to be covered (subject to change)
- Sorting
- Hashing
- Dynamic Programming
- Trees
- Graphs
- SAT Solvers (time permitting)
Required and Recommended Course Material: No textbook is required for this course. Lecture will contain overviews of the ideas and concepts needed for the topic at hand, but much of this course is intended for you to practice skills you’ve accumulated thusfar as a student.
When relevant or helpful, I will provide links to free materials to help study topics and concepts in this course. Please keep an eye out for changes to the website with these resources. Office hours and Piazza discussions will also help you greatly during this course.
Course Copyright: Please protect the copyright integrity of all course materials and content. Please do not upload course materials not created by you onto third-party websites or share content with anyone not enrolled in our course.
The purpose of this syllabus is to give students guidance on what may be covered during the semester. I intend to follow the syllabus as closely as possible; however, I also reserve the right to modify, supplements, and/or make changes to the course as needs arise. All such changes will be communicated in advance through in-class annoucnements and in writing via this website and email.
Course Policies and Classroom Expectations
Grading Policies & Point Breakdown
Grades will be curved based on an aggregate course score and are not defined ahead of time. The score cut-offs for A, B, C, etc., will be set after the end of the course.
The course will have the following grade breakdown:
| Task | % of total grade |
|---|---|
| In-class Presentation and Discussion | 20% |
| In-class Reports | 15% |
| Projects | 25% |
| Midterm Exam | 15% |
| Final Exam | 25% |
Final Grade Assignments
My goal is to ensure that the assessment of your learning in this course is comprehensive, fair, and equitable. Your grade in the class will be based on the number of points you earn out of the total number of points possible, and is not based on your rank relative to other students. There are no set limits to the number of grades given (e.g., everyone can get an A if everyone does well).
Under no circumstances will grades be adjusted down (except in cases of course policy violation). You can use this straight grading scale as an indicator of your minimum grade in the course at any time during the course. You should keep track of your own points so that at any time during the semester you may calculate your minimum grade based on the total number of points possible at that particular time. If and when, for any reason, you have concerns about your grade in the course, please email me to schedule a time for you to speak with me so that we can discuss study techniques or alternative strategies to help you.
Regrade Policy
You are allowed to request one single regrade per project/non-final exam. Moreover, with every regrade request, you must submit the following information:
- Which problems you are requesting a regrade for; and
- The exact reason you are requesting a regrade.
I will be strict with this policy to ensure there are no frivolous regrade requests; i.e., do not request a regrade to try and argue for more points. You must have a specific and articulate reason for why you believe something was graded incorrectly. Finally, note that any regrade request can result in a score reduction if additional errors are discovered.
Assignment Late Policy
Each assignment will have a set due date. You may submit assignments late, with a 25% point reduction per day of being late. On the fourth or later day of being late, you will recieve zero points on the assignment, but if you submit the assignment, it will still be graded in order to give you feedback.
In-class Participation
As this class emphasizes many soft skills and in-class participation, it is highly encouraged that you attend class. Much of your grade relies on in-class participation.
You are expected to attend class every week, stay for the entire duration of class, and be an active participant. Lack of attendance, leaving early, and not participating will be detremental to your grade. However, I do understand that things happen (important meeting conflicts with class, unexpected sickness, etc.). So, for this course, you are allowed to have 4 unexcused absences from class, no questions asked. For all other absences and/or if you need to leave early, you will need to notify me with supporting documentation for your reasons.
In-class Presentation and Discussion
Each week, a group (or groups) of students will be asked to present their ideas and solutions to the class. Essentially, you will lead the discussion and answer questions/comments from other students, and myself. You will be evaluated on your presentation, your (attempted) solution, and your discussion.
For this reason, it is essential you attend class. Not every student/group will be required to present each week, but every student/group will be expected to participate in the discussion that comes with the presentations. Full details about in-class presentations and discussions can be found under the In-class Work section of this website.
In-class Report
To conclude every week of class, all students will individually submit a report. This report will discuss the problem(s) we tackled during class, what the student did to tackle this problem (individually or in a group), and how the discussion helped confirm your solution or helped you find the right solution/clarify your answer.
This report is not meant to be a super formal write-up, but rather to help track your progress and understanding during the semester. Moreover, you are allowed to miss/drop 2 of these reports throughout the semester, no questions asked. Full details about in-class reports can be found under the In-class Work section of this website.
Projects
As this course is meant to give you ample practice reinforcing your skills, there will be a series of programming projects throughout the semester. The current expectation is 4-6 projects depending on the course pacing; i.e., at most one project for each topic covered, maybe a project that incorporates more topics (note this does not mean course concepts will not overlap between topics and projects).
All projects will use the C++ programming language, unless otherwise stated. Your lowest project grade will be automatically dropped. Projects will also require a report and/or office hours presentations alongside the submitted code. Full details about course projects can be found under the Projects section of this website.
Midterm Exam
There will be an in-class midterm exam, covering topics from (roughly) the first half of the course. The tentative date for the midterm exam is Thursday, October 16, 2025, with an in-class review planned for the previous lecture on Tuesday, October 14, 2025. Please plan to attend class on this day for the midterm exam. I will notify all students once the midterm exam date is finalized, and will do so as soon as possible.
Final Exam
There will also be an in-person, written final exam. You are required to take this exam, barring extraneous circumstances. Students who do not take the final exam will be unable to receive a passing grade in this course. Moreover, do not expect to get a passing grade if you simply show up, write your name on the exam, and don’t do the exam (or some variation of this).
Academic Integrity
Consulting with your classmates on assignments is encouraged, except where noted. However, turn-ins are individual or group-based, and copying code/text from your classmates is considered plagiarism (in the case of individual reports, copying your group memeber’s report is also plagiarism). You should never look at someone else’s writing/code, or show someone else your writing/code, unless otherwise directed by the instructor. Either of these actions are considered academic dishonesty (cheating) and will be prosecuted as such.
To avoid suspicion of plagiarism, you must specify your sources together with all turned-in materials. List classmates you discussed your homework with and webpages/resources (this includes AI usage) from which you got inspiration and help. Plagiarism and cheating, as in copying the work of others, paying others to do your work, etc., is obviously prohibited, and will be reported (this includes asking questions and copying answers from forums such as Stack Overflow and Reddit).
I report all suspected academic integrity violations to the dean of students. If it is your first time, the dean of students may provide the option to informally resolve the case – this means the student agrees that my description of what happened is accurate, and the only repercussions on an institutional level are that it is noted that this happened in your internal, UIC files (i.e., the dean of students can see that this happened, but no professors or other people can, and it is not in your transcript). If this is not your first academic integrity violation in any of your classes, a formal hearing is held and the dean of students decides on the institutional consequences. After multiple instances of academic integrity violations, students may be suspended or expelled. For all cases, the student has the option to go through a formal hearing if they believe that they did not actually violate the academic integrity policy. If the dean of students agrees that they did not, then I revert their grade back to the original grade, and the matter is resolved.
If you are found responsible for violating the academic integrity policy, the penalty can range from receiving a zero on the assignment in question, receiving a grade deduction, or receiving an F in the class, depending on the severity of the violation.
As a student and member of the UIC community, you are expected to adhere to the Community Standards of academic integrity, accountability, and respect. Please review the UIC Student Disciplinary Policy for additional information.
GenAI
Usage of GenAI is allowed in this course. However, you are expected to use GenAI as a tool to help you, and not as a tool to do the work for you. These are two completely different things. This means you should not be submitting any assignment in this course that is completely written by AI. Doing so constitutes a violation of the course conduct policy and will be appropriately punished.
Failure to adhere to this policy will result in the following consequences:
- First use: You will lose 50% of the points available on the assignment.
- Second use: You will fail the assignment.
- Third use: You will fail the course.
GenAI has helped and hindered new and old programmers alike, and it is in your best interest to use GenAI properly to help you solve problems, not solve them for you (as they will often include extra/incorrect/bloated code). See this article exploring the harm GenAI has done to new programmers.
Accommodations
Disability Accommodation Procedures
UIC is committed to full inclusion and participation of people with disabilities in all aspects of university life. If you face or anticipate disability-related barriers while at UIC, please connect with the Disability Resource Center (DRC) at drc.uic.edu, via email at drc@uic.edu, or call (312) 413-2183 to create a plan for reasonable accommodations. To receive accommodations, you will need to disclose the disability to the DRC, complete an interactive registration process with the DRC, and provide me with a Letter of Accommodation (LOA). Upon receipt of an LOA, I will gladly work with you and the DRC to implement approved accommodations.
Religious Accommodations
Following campus policy, if you wish to observe religious holidays, you must notify me by the tenth day of the semester. If the religious holiday is observed on or before the tenth day of the semester, you must notify me at least five days before you will be absent. Please submit this form by email with the subject heading: “[CS 402 Fall 2025] YOUR NAME: Requesting Religious Accommodation.”
Classroom Environment
Inclusive Community
UIC values diversity and inclusion. Regardless of age, disability, ethnicity, race, gender, gender identity, sexual orientation, socioeconomic status, geographic background, religion, political ideology, language, or culture, we expect all members of this class to contribute to a respectful, welcoming, and inclusive environment for every other member of our class. If aspects of this course result in barriers to your inclusion, engagement, accurate assessment, or achievement, please notify me as soon as possible.
Name and Pronoun Use
If your name does not match the name on my class roster, please let me know as soon as possible. My pronouns are [she/her; he/him; they/them]. I welcome your pronouns if you would like to share them with me. For more information about pronouns, see this page: https://www.mypronouns.org/what-and-why.
Community Agreement/Classroom Conduct Policy
- Be present by removing yourself from distractions, whether they be phone notifications, entire devices, conversations, or anything else.
- Be respectful of the learning space and community. For example, no side conversations or unnecessary disruptions.
- Use preferred names and gender pronouns.
- Assume goodwill in all interactions, even in disagreement.
- Facilitate dialogue and value the free and safe exchange of ideas.
- Try not to make assumptions, have an open mind, seek to understand, and not judge.
- Approach discussion, challenges, and different perspectives as an opportunity to “think out loud,” learn something new, and understand the concepts or experiences that guide other people’s thinking.
- Debate the concepts, not the person.
- Be gracious and open to change when your ideas, arguments, or positions do not work or are proven wrong.
- Be willing to work together and share helpful study strategies.
- Be mindful of one another’s privacy, and do not invite outsiders into our classroom.
Furthermore, our class (in person and online) will follow the CS Code of Conduct. If you are not adhering to our course norms, a case of behavior misconduct will be submitted to the Dean of Students and to the Director of Undergraduate Studies in the department of Computer Science. If you are not adhering to our course norms, you will not get full credit for your work in this class. For extreme cases of violating the course norms, credit for the course will not be given.
Student Parents
I know well how exhausting balancing school, childcare, and work can be. I would like to help support you and accommodate your family’s needs, so please don’t keep me in the dark. I hope you will feel safe disclosing your student-parent status to me so that I can help you anticipate and solve problems in a way that makes you feel supported. Unforeseen disruptions in childcare often put parents in the position of having to choose between missing classes to stay home with a child or leaving them with a less desirable backup arrangement. While this is not meant to be a long-term childcare solution, occasionally bringing a child to class in order to cover gaps in care is perfectly acceptable. If your baby or young child comes to class with you, please plan to sit close to the door so that you can step outside without disrupting learning for other students if your child needs special attention. Non-parents in the class, please reserve seats near the door for your parenting classmates or others who may need to step out briefly.
Academic Success, Wellness, and Safety
We all need the help and the support of our UIC community. Please visit my drop-in hours for course consultation and other academic or research topics. For additional assistance, please contact your assigned college advisor and visit the support services available to all UIC students.
Academic Success
- UIC Tutoring Resources
- College of Engineering tutoring program
- Equity and Inclusion in Engineering Program
- UIC Library and UIC Library Research Guides.
- Offices supporting the UIC Undergraduate Experience and Academic Programs.
- Student Guide for Information Technology
- First-at-LAS Academic Success Program, focusing on LAS first-generation students.
Wellness
-
Counseling Services : You may seek free and confidential services from the Counseling Center at https://counseling.uic.edu/.
-
Access U&I Care Program for assistance with personal hardships.
-
Campus Advocacy Network : Under Title IX, you have the right to an education that is free from any form of gender-based violence or discrimination. To make a report, email TitleIX@uic.edu. For more information or confidential victim services and advocacy, visit UIC’s Campus Advocacy Network at http://can.uic.edu/.
Safety
- UIC Safe App—PLEASE DOWNLOAD FOR YOUR SAFETY!
- UIC Safety Tips and Resources
- Night Ride
- Emergency Communications: By dialing 5-5555 from a campus phone, you can summon the Police or Fire for any on-campus emergency. You may also set up the complete number, (312) 355-5555, on speed dial on your cell phone.
Schedule
This schedule is tentative and subject to change. Any changes will be announced.
| Week (Dates) | Topics | Announcements | Additional Resources |
|---|---|---|---|
| Week 1 (08/26, 08/28) |
| ||
| Week 2 (09/02, 09/04) |
| ||
| Week 3 (09/09, 09/11) |
| Project 1 released. | |
| Week 4 (09/16, 09/18) |
| ||
| Week 5 (09/23, 09/25) |
| ||
| Week 6 (09/30, 10/02) |
| ||
| Week 7 (10/07, 10/09) |
| ||
| Week 8 (10/14, 10/16) |
| ||
| Week 9 (10/21, 10/23) |
| Project 2 released. | |
| Week 10 (10/28, 10/30) |
| ||
| Week 11 (11/04, 11/06) |
| ||
| Week 12 (11/11, 11/13) |
| ||
| Week 13 (11/18, 11/20) |
| Project 3 released. | |
| Week 14 (11/25) |
| ||
| Week 15 (12/02, 12/04) |
| ||
| Week 16 (Finals Week) |
|
Resources
Throughout the semester, I will fill this webpage with useful resources. Most (if not all) of these resources will be freely available online.
In-Class LeetCode
In this section, I will post the LeetCode problems we have tackled in class, as well as the code we wrote to solve the problems. This section will continue to grow throughout the semester. Note that it is posted in reverse chronological order (most recent problems are posted first).
Minimum Cost to Cut a Stick
Link; (Dynamic Programming, Nov. 25, 2025)
Top-down DP (Memoization)
class Solution {
vector<vector<int>> dp;
public:
int computeCost(int i, int j, int start, int end, vector<int>& cuts) {
if(i > j) return 0;
if(dp[i][j] != 0) return dp[i][j];
int minCost = INT_MAX;
for(int k = i; k <= j; k++) {
int left = computeCost(i, k-1, start, cuts[k], cuts);
int right = computeCost(k+1, j, cuts[k], end, cuts);
int my_cost = end - start;
minCost = min(minCost, left+right+my_cost);
}
dp[i][j] = minCost;
return dp[i][j];
}
int minCost(int n, vector<int>& cuts) {
int s = cuts.size();
sort(cuts.begin(), cuts.end());
dp = vector<vector<int>>(s, vector<int>(s));
return computeCost(0, s-1, 0, n, cuts);
}
};
Bottom-up DP (Tabulation)
class Solution {
vector<vector<int>> dp;
public:
int minCost(int n, vector<int>& cuts) {
int s = cuts.size();
sort(cuts.begin(), cuts.end());
dp = vector<vector<int>>(s, vector<int>(s));
// tabulation
for(int i = s-1; i>=0; --i) {
for(int j = i; j < s; ++j) {
int minCost = INT_MAX;
int start = 0;
if(i > 0) start = cuts[i-1];
int end = n;
if(j < s-1) end = cuts[j+1];
for(int k = i; k <= j; ++k) {
int left = 0;
int right = 0;
if(k > i) left = dp[i][k-1];
if(k < j) right = dp[k+1][j];
minCost = min(minCost, left+right+(end-start));
}
dp[i][j] = minCost;
}
}
return dp[0][s-1];
}
};
Binary Tree Maximum Path Sum
Link; (Dynamic Programming, Nov. 20, 2025)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int global_max = numeric_limits<int>::min();
int findMax(TreeNode* root) {
if(root == nullptr) return 0;
int left = max(0, findMax(root->left));
int right = max(0, findMax(root->right));
global_max = max(global_max, root->val + left + right);
return root->val + max(left, right);
}
int maxPathSum(TreeNode* root) {
findMax(root);
return global_max;
}
};
Dungeon Game
Link; (Dynamic Programming, Nov. 18, 2025)
class Solution {
public:
int calculateMinimumHP(vector<vector<int>>& dungeon) {
int m = dungeon.size();
int n = dungeon[0].size();
vector<vector<int>> dp(m+1, vector<int>(n+1, INT_MAX));
dp[m][n-1] = 1;
dp[m-1][n] = 1;
for(int i = m-1; i >= 0; --i) {
for(int j = n-1; j >= 0; --j) {
int val = min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j];
dp[i][j] = (val <= 0) ? 1 : val;
// if(val <= 0) {
// dp[i][j] = 1;
// }
// else {
// dp[i][j] = val;
// }
}
}
return dp[0][0];
}
};
Binary Tree Cameras
Link; (Dynamic Programming + Trees, Nov. 13, 2025)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> memoization;
int dp(TreeNode* root, int state) {
if(root == nullptr) {
return state==2;
}
else if(memoization[root->val][state]!= -1) {
return memoization[root->val][state];
}
else {
int cur_val = INT_MAX;
switch(state) {
case 2: {
cur_val = min(cur_val, 1+dp(root->left,1) + dp(root->right,1));
break;
}
case 1: {
cur_val = min(cur_val, dp(root->left,0) + dp(root->right,0));
cur_val = min(cur_val, 1+dp(root->left,1)+dp(root->right,1));
break;
}
default: { // case 0
cur_val = min(cur_val,1+dp(root->left,1)+dp(root->right,1));
cur_val = min(cur_val, dp(root->left,2)+dp(root->right,0));
cur_val = min(cur_val, dp(root->left,0)+dp(root->right,2));
break;
}
}
memoization[root->val][state] = cur_val;
return memoization[root->val][state];
}
}
void dfs(int& n, TreeNode* root) {
if(root == nullptr) return;
root->val=n++;
dfs(n,root->left);
dfs(n, root->right);
}
int minCameraCover(TreeNode* root) {
if(root == nullptr) return 0;
int n = 0;
dfs(n, root);
memoization = vector<vector<int>>(n);
for(int i = 0; i < n; ++i) {
memoization[i] = {-1, -1, -1};
}
return dp(root,0);
}
};
Binary Trees With Factors
Link; (Dynamic Programming + Trees, Nov. 13, 2025)
class Solution {
public:
int numFactoredBinaryTrees(vector<int>& arr) {
long result = 0;
long mod = pow(10,9) + 7;
unordered_map<int, long> tablu;
sort(arr.begin(), arr.end()); //arr[i], arr[j] for j < i
for(int i = 0; i < arr.size(); ++i) {
tablu[arr[i]] = 1;
for(int j = 0; j < i; ++j) {
// [2, 4, 8, 16]
if(arr[i] % arr[j] == 0) {
tablu[arr[i]] = (tablu[arr[i]] + tablu[arr[j]]*tablu[arr[i]/arr[j]]) % mod;
}
}
result = (result + tablu[arr[i]]) % mod;
}
return result;
}
};
Fibonacci Number
Link; (Dynamic Programming, Nov. 11, 2025)
class Solution {
public:
int fib_recurse(int n) {
// bad exp time!
if(n == 0 || n == 1) {
return n;
}
else return fib_recurse(n-1) + fib_recurse(n-2);
}
int fib_memo_help(vector<int>& table, int n) {
if(n == 0) {
return 0;
}
if(table[n] > 0) {
return table[n];
}
table[n] = fib_memo_help(table, n-1) + fib_memo_help(table, n-2);
return table[n];
}
int fib_top_down_memo(int n) {
vector<int> table(n+1,0);
table[1] = 1;
return fib_memo_help(table,n);
}
int fib_bottom_up(int n) {
if(n == 0 || n == 1) {
return n;
}
int val0 = 0;
int val1 = 1;
for(int i = 2; i < n+1; ++i) {
int tmp = val1;
val1 = val1+val0;
val0 = tmp;
}
return val1;
}
int fib(int n) {
return fib_bottom_up(n);
}
};
Serialize and Deserialize Binary Tree
Link (Trees, Nov. 6, 2025)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
const string null = "null";
// Encodes a tree to a single string.
string val_to_str(int val) {
int shifted_val = 1000+val;
string out = to_string(shifted_val);
while(out.size() < 4) {
out = "0" + out;
}
return out;
}
int str_to_val(string str) {
// assumes str is of length 4
int val = stoi(str);
val = val-1000;
return val;
}
string serialize(TreeNode* root) {
if(root == nullptr) return null;
string out = "";
// construct pre-order DFS string
out += val_to_str(root->val);
out += serialize(root->left);
out += serialize(root->right);
return out;
}
TreeNode* deserialize_help(string& data, unsigned int& start_pos) {
string curr = data.substr(start_pos,4);
//data.erase(0,4);
if(curr == null) return nullptr;
TreeNode* root = new TreeNode(str_to_val(curr));
start_pos += 4;
root->left = deserialize_help(data, start_pos);
start_pos +=4;
root->right = deserialize_help(data, start_pos);
return root;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
//string data_copy(data);
unsigned int start = 0;
return deserialize_help(data, start);
}
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));
Tree of Coprimes
Link (Trees, Nov. 4, 2025)
class Solution {
public:
vector<vector<int>> tree;
unordered_map<int, vector<int>> coprimes;
unordered_map<int, vector<pair<int, int>>> path;
void DFS(int curr_id, int curr_depth, int parent_id, vector<int>& nums, vector<int>& ans) {
// check if nums[curr_id] is coprime to anything in the current path
int max_depth = -1;
for(int val: coprimes[nums[curr_id]]) {
vector<pair<int,int>>& ancestors = path[val];
if(!ancestors.empty() && ancestors.back().second > max_depth) {
max_depth = ancestors.back().second;
ans[curr_id] = ancestors.back().first;
}
}
path[nums[curr_id]].push_back({curr_id, curr_depth});
for(int child_id : tree[curr_id]) {
if(child_id != parent_id) {
DFS(child_id, curr_depth+1, curr_id, nums, ans);
}
}
path[nums[curr_id]].pop_back();
}
vector<int> getCoprimes(vector<int>& nums, vector<vector<int>>& edges) {
int n = nums.size();
vector<int> ans = vector<int>(n, -1);
tree = vector<vector<int>>(n);
// Build the tree
for(const auto edge: edges) {
tree[edge[0]].push_back(edge[1]);
tree[edge[1]].push_back(edge[0]);
}
unordered_set<int> set(nums.begin(), nums.end());
for(int n1 : set) {
for(int n2 : set) {
if(gcd(n1, n2) == 1) coprimes[n1].push_back(n2);
}
}
DFS(0, 0, -1, nums, ans);
return ans;
}
};
Binary Tree Level Order Traversal
Link (Trees, Oct. 30, 2025)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
if(root == nullptr) return {};
queue<TreeNode*> bfs_queue;
bfs_queue.push(root);
vector<vector<int>> output {};
while(!bfs_queue.empty()) {
int num_in_lvl = bfs_queue.size();
vector<int> curr_lvl_order {};
while(num_in_lvl > 0) {
TreeNode* curr = bfs_queue.front();
bfs_queue.pop();
--num_in_lvl;
curr_lvl_order.push_back(curr->val);
if(curr->left != nullptr) {
bfs_queue.push(curr->left);
}
if(curr->right != nullptr) {
bfs_queue.push(curr->right);
}
}
output.push_back(curr_lvl_order);
}
return output;
}
};
Construct Binary Tree from Inorder and Postorder Traversal
Link (Trees, Oct. 16, 2025)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
// we'll use a hashmap so we don't have to search through the inorder vector every time!
unordered_map<int, int> hash_map;
// int_end is inclusive;
TreeNode* buildSubtree(
vector<int>& inorder,
vector<int>& postorder,
int in_start,
int in_end,
int& post_root_index
) {
if(in_start > in_end) return nullptr;
TreeNode* root = new TreeNode(postorder[post_root_index--]);
int inorder_root_index = hash_map[root->val];
int right_size = in_end - inorder_root_index;
root->right = buildSubtree(inorder, postorder, inorder_root_index+1, in_end, post_root_index);
root->left = buildSubtree(inorder, postorder, in_start, inorder_root_index-1, post_root_index);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
for(int i = 0; i < inorder.size(); ++i) {
hash_map[inorder[i]] = i;
}
int n = inorder.size();
int post_root_index = n-1;
return buildSubtree(inorder, postorder, 0, n-1, post_root_index);
}
};
Minimum Height Trees
Link (Trees, Oct. 14, 2025)
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
if(n == 1) return vector<int>{0};
vector<vector<int>> tree(n);
vector<int> degree(n, 0);
for(vector<int> edge: edges) {
tree[edge[0]].push_back(edge[1]);
tree[edge[1]].push_back(edge[0]);
++degree[edge[0]];
++degree[edge[1]];
}
vector<int> output;
queue<int> deg_1_queue;
for(int i = 0; i < n; ++i) {
if(degree[i] == 1) deg_1_queue.push(i);
}
while(!deg_1_queue.empty()) {
int queue_size = deg_1_queue.size();
output.clear();
while(queue_size) {
int curr = deg_1_queue.front();
deg_1_queue.pop();
output.push_back(curr);
for(int i = 0; i < tree[curr].size(); ++i) {
--degree[tree[curr][i]];
if(degree[tree[curr][i]]==1) {
deg_1_queue.push(tree[curr][i]);
}
}
--queue_size;
}
}
return output;
}
};
Shortest Path with Alternating Colors
Link (Graphs, Oct. 14, 2025) DFS approach.
class Solution {
public:
vector<vector<int>> red_graph;
vector<vector<int>> blue_graph;
vector<int> shortest_red;
vector<int> shortest_blue;
void calcShortest(int node, int path_len, char edge_color) {
switch(edge_color) {
case 'b':
if(shortest_blue[node] == -1 || path_len < shortest_blue[node]) {
shortest_blue[node] = path_len;
for(int i = 0; i < red_graph[node].size(); ++i) {
calcShortest(red_graph[node][i], path_len+1, 'r');
}
}
break;
case 'r':
if(shortest_red[node] == -1 || path_len < shortest_red[node]) {
shortest_red[node] = path_len;
for(int i = 0; i < blue_graph[node].size(); ++i) {
calcShortest(blue_graph[node][i], path_len+1, 'b');
}
}
break;
default:
throw std::invalid_argument( "received incorrect edge color" );
}
}
vector<int> shortestAlternatingPaths(int n, vector<vector<int>>& redEdges, vector<vector<int>>& blueEdges) {
red_graph = vector<vector<int>>(n);
blue_graph = vector<vector<int>>(n);
shortest_red = vector<int>(n);
shortest_blue = vector<int>(n);
// these will track the shortest paths from node 0 to node i when entering
// node i from the respective color
shortest_red[0] = 0;
shortest_blue[0] = 0;
// init all path lengths
for(int i = 1; i < n; ++i) {
shortest_red[i] = -1;
shortest_blue[i] = -1;
}
// construct the graphs
for(vector<int> redge: redEdges) {
red_graph[redge[0]].push_back(redge[1]);
}
for(vector<int> bedge: blueEdges) {
blue_graph[bedge[0]].push_back(bedge[1]);
}
for(int i = 0; i < red_graph[0].size(); ++i) {
calcShortest(red_graph[0][i], 1, 'r');
}
for(int i = 0; i < blue_graph[0].size(); ++i) {
calcShortest(blue_graph[0][i], 1, 'b');
}
vector<int> output(n);
output[0] = 0;
for(int i = 1; i < n; ++i) {
if(shortest_red[i] == -1 && shortest_blue[i] == -1) {
output[i] = -1;
}
else if(shortest_red[i] == -1) {
output[i] = shortest_blue[i];
}
else if(shortest_blue[i] == -1) {
output[i] = shortest_red[i];
}
else {
output[i] = (shortest_red[i] <= shortest_blue[i]) ? shortest_red[i] : shortest_blue[i];
}
}
return output;
}
};
BFS approach.
class Solution {
public:
vector<vector<int>> red_graph;
vector<vector<int>> blue_graph;
vector<int> shortest_red;
vector<int> shortest_blue;
vector<int> shortestAlternatingPaths(int n, vector<vector<int>>& redEdges, vector<vector<int>>& blueEdges) {
red_graph = vector<vector<int>>(n);
blue_graph = vector<vector<int>>(n);
shortest_red = vector<int>(n);
shortest_blue = vector<int>(n);
// these will track the shortest paths from node 0 to node i when entering
// node i from the respective color
shortest_red[0] = 0;
shortest_blue[0] = 0;
// init all path lengths
for(int i = 1; i < n; ++i) {
shortest_red[i] = -1;
shortest_blue[i] = -1;
}
// construct the graphs
for(vector<int> &redge: redEdges) {
red_graph[redge[0]].push_back(redge[1]);
}
for(vector<int> &bedge: blueEdges) {
blue_graph[bedge[0]].push_back(bedge[1]);
}
// BFS approach
queue<vector<int>> bfs_queue;
// 0 = red; 1 = blue
bfs_queue.push({0, 0});
bfs_queue.push({0, 1});
while(!bfs_queue.empty()) {
vector<int> curr_list = bfs_queue.front();
bfs_queue.pop();
int curr_node = curr_list[0];
int curr_color = curr_list[1];
// if coming from red, search all blue
if(curr_color == 0) {
int distance = shortest_red[curr_node];
for(int neigh: blue_graph[curr_node]) {
if(shortest_blue[neigh] == -1 || distance+1 < shortest_blue[neigh]) {
shortest_blue[neigh] = distance + 1;
bfs_queue.push({neigh, 1});
}
}
}
else { // if coming from blue, search all red
int distance = shortest_blue[curr_node];
for(int neigh: red_graph[curr_node]) {
if(shortest_red[neigh] == -1 || distance+1 < shortest_red[neigh]) {
shortest_red[neigh] = distance + 1;
bfs_queue.push({neigh, 0});
}
}
}
}
vector<int> output(n);
output[0] = 0;
for(int i = 1; i < n; ++i) {
if(shortest_red[i] == -1 && shortest_blue[i] == -1) {
output[i] = -1;
}
else if(shortest_red[i] == -1) {
output[i] = shortest_blue[i];
}
else if(shortest_blue[i] == -1) {
output[i] = shortest_red[i];
}
else {
output[i] = (shortest_red[i] <= shortest_blue[i]) ? shortest_red[i] : shortest_blue[i];
}
}
return output;
}
};
Cheapest Flights within K Stops
Link (Graphs, Oct. 9, 2025)
const int infinity = std::numeric_limits<int>::max();
struct Node {
int id;
int price;
int stop_num;
vector<Node> neighbors;
bool operator> (const Node&) const;
bool operator>=(const Node&) const;
bool operator==(const Node&) const;
bool operator< (const Node&) const;
bool operator<=(const Node&) const;
bool operator!=(const Node&) const;
};
bool Node::operator> (const Node& node) const {return price > node.price; }
bool Node::operator>=(const Node& node) const {return price >= node.price; }
bool Node::operator==(const Node& node) const {return price == node.price; }
bool Node::operator< (const Node& node) const {return price < node.price; }
bool Node::operator<=(const Node& node) const {return price <= node.price; }
bool Node::operator!=(const Node& node) const{return price != node.price; }
class Solution {
public:
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
vector<Node> graph;
for(int i = 0; i < n; ++i) {
graph.push_back(Node(i, infinity, infinity, {}));
}
for(vector<int> edge: flights) {
graph[edge[0]].neighbors.push_back(Node(edge[1], edge[2], 0, {}));
}
priority_queue<Node, std::vector<Node>, std::greater<Node>> min_queue;
min_queue.push(Node(src, 0, 0, {}));
while(!min_queue.empty()) {
Node curr = min_queue.top();
min_queue.pop();
if(curr.id == dst) return curr.price;
if(curr.stop_num > k || curr.stop_num > graph[curr.id].stop_num) continue;
graph[curr.id].stop_num = curr.stop_num;
for(Node neigh: graph[curr.id].neighbors) {
min_queue.push(Node(neigh.id, curr.price+neigh.price, curr.stop_num+1));
}
}
return -1;
}
};
Alternative, more elegant solution from LeetCode contributor.
const int infinity = std::numeric_limits<int>::max();
class Solution {
public:
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
vector<vector<vector<int>>> graph(n);
for(vector<int> edge: flights) {
// graph[i] is a vector<vector<int>>
// graph[i][j] is a vector<int> of the form: { to_id, price }
graph[edge[0]].push_back({edge[1], edge[2]});
}
// track current number of stops of each node
vector<int> num_stops(n, infinity);
// nodes are stored in the form: { price, id, num_stops}
priority_queue<array<int,3>, vector<array<int,3>>, greater<>> min_queue;
min_queue.push({0, src, 0});
while(!min_queue.empty()) {
auto [price, id, stops] = min_queue.top();
min_queue.pop();
if(id == dst) return price;
if(stops > k || stops > num_stops[id]) continue;
num_stops[id] = stops;
for(int i = 0; i < graph[id].size(); ++i) {
min_queue.push({price + graph[id][i][1], graph[id][i][0], stops+1});
}
}
return -1;
}
};
Course Schedule II
Link (Graphs, Oct. 2, 2025)
Note that this also solves Course Schedule.
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
// First, make graph via adj list!
vector<vector<int>> graph(numCourses);
vector<int> visited(numCourses);
// Our graph representation will be a predecessor representation. That is,
// graph[i] is a list / hashmap of all the nodes j such that (j,i) is an edge.
// In other words, graph[i] contains all courses j that are a prereq for i.
for(vector<int> prereq: prerequisites) {
graph[ prereq[0] ].push_back( prereq[1] );
}
// Now, we need to topologically sort the graph. You can do this via BFS or DFS.
// vector representing the final ordering
vector<int> order {};
// BFS approach
queue<int> bfs_queue {};
// we need to find all nodes with no predecessors so we can start our sorting algorithm
for(int i = 0; i < numCourses; ++i) {
if(graph[i].empty()) {
bfs_queue.push(i);
visited[i] = 1;
}
}
//if(bfs_queue.empty()) return order; // return empty list!
while(!bfs_queue.empty()) {
int curr = bfs_queue.front();
bfs_queue.pop();
order.push_back(curr);
for(int i = 0; i < numCourses; ++i) {
if(i == curr) continue;
for(int j = 0; j < graph[i].size(); ++j) {
if(graph[i][j] == curr) {
graph[i].erase(graph[i].begin()+j);
break;
}
}
if(graph[i].empty() && !visited[i]) {
bfs_queue.push(i);
visited[i] = 1;
}
}
}
if(order.size() < numCourses) return vector<int>();
return order;
}
};
Number of Islands
Link (Graphs, Sept. 30 and Oct. 2, 2025)
DFS Approach.
class Solution {
public:
// Return the index of pair (row, col) in row-major order
int pair_to_index(const int row, const int col, const int num_cols) {
return (num_cols*row + col);
}
void recursive_dfs(vector<vector<char>>& grid, int num_rows, int num_cols, int i, int j, vector<bool>& visited) {
// visit the current node
visited[pair_to_index(i,j, num_cols)] = true;
// visit in clockwise order starting from the top
// visit north
if(i > 0 && grid[i-1][j] == '1' && !visited[pair_to_index(i-1,j, num_cols)]) {
recursive_dfs(grid, num_rows, num_cols, i-1, j, visited);
}
// visit east
if(j < num_cols-1 && grid[i][j+1] == '1' && !visited[pair_to_index(i,j+1, num_cols)]) {
recursive_dfs(grid, num_rows, num_cols, i, j+1, visited);
}
// visit south
if(i < num_rows-1 && grid[i+1][j] == '1' && !visited[pair_to_index(i+1,j, num_cols)]) {
recursive_dfs(grid, num_rows, num_cols, i+1, j, visited);
}
// visit west
if(j > 0 && grid[i][j-1] == '1' && !visited[pair_to_index(i,j-1, num_cols)]) {
recursive_dfs(grid, num_rows, num_cols, i, j-1, visited);
}
return;
}
int numIslands(vector<vector<char>>& grid) {
int m = grid.size();
int n = grid[0].size();
int num_islands = 0;
int total_size = m * n;
vector<bool> visited(total_size);
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(grid[i][j] == '1' && !visited[pair_to_index(i, j, n)]) {
// recursive DFS
recursive_dfs(grid, m, n, i, j, visited);
++num_islands;
}
}
}
return num_islands;
}
};
BFS Approach.
class Solution {
public:
// Return the index of pair (row, col) in row-major order
int pair_to_index(const int row, const int col, const int num_cols) {
return (num_cols*row + col);
}
int index_to_row(const int index, const int num_cols) {
return index / num_cols;
}
int index_to_col(const int index, const int num_cols) {
return index % num_cols;
}
int numIslands(vector<vector<char>>& grid) {
int m = grid.size();
int n = grid[0].size();
int num_islands = 0;
int total_size = m * n;
vector<bool> visited(total_size);
queue<int> bfs_queue;
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(grid[i][j] == '1' && !visited[pair_to_index(i, j, n)]) {
visited[pair_to_index(i,j,n)] = true;
// Loop BFS
bfs_queue.push(pair_to_index(i,j,n));
while(!bfs_queue.empty()) {
int index = bfs_queue.front();
bfs_queue.pop();
int row = index_to_row(index, n);
int col = index_to_col(index, n);
// visit the node
visited[index] = true;
// do BFS, clockwise starting north
// visit north
if(row > 0 && grid[row-1][col] == '1' && !visited[pair_to_index(row-1, col, n)]) {
visited[pair_to_index(row-1,col,n)] = true;
bfs_queue.push(pair_to_index(row-1, col, n));
}
// visit east
if(col < n-1 && grid[row][col+1] == '1' && !visited[pair_to_index(row,col+1, n)]) {
visited[pair_to_index(row,col+1,n)] = true;
bfs_queue.push(pair_to_index(row, col+1, n));
}
// visit south
if(row < m-1 && grid[row+1][col] == '1' && !visited[pair_to_index(row+1,col, n)]) {
visited[pair_to_index(row+1,col,n)] = true;
bfs_queue.push(pair_to_index(row+1, col, n));
}
// visit west
if(col > 0 && grid[row][col-1] == '1' && !visited[pair_to_index(row,col-1, n)]) {
visited[pair_to_index(row,col-1,n)] = true;
bfs_queue.push(pair_to_index(row, col-1, n));
}
}
++num_islands;
}
}
}
return num_islands;
}
};
Clone Graph
Link (Graphs, Sept. 25, 2025)
/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> neighbors;
Node() {
val = 0;
neighbors = vector<Node*>();
}
Node(int _val) {
val = _val;
neighbors = vector<Node*>();
}
Node(int _val, vector<Node*> _neighbors) {
val = _val;
neighbors = _neighbors;
}
};
*/
class Solution {
public:
Node* cloneGraph(Node* node) {
queue<Node*> bfs_queue {};
unordered_map<int, Node*> cloned_nodes {};
if(node == nullptr) {
return nullptr;
}
Node* clone_start = new Node(node->val);
cloned_nodes[clone_start->val] = clone_start;
bfs_queue.push(node);
while(!bfs_queue.empty()) {
Node* curr = bfs_queue.front();
bfs_queue.pop();
for(Node* neigh: curr->neighbors) {
cout << neigh->val << ", ";
if(!cloned_nodes[neigh->val]) {
cloned_nodes[neigh->val] = new Node(neigh->val);
bfs_queue.push(neigh);
}
cloned_nodes[curr->val]->neighbors.push_back(cloned_nodes[neigh->val]);
}
}
return clone_start;
}
};
Group Anagrams
Link (Hashing, Sept. 18, 2025)
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
// step 1: given a string s, make new string s' where s' is char's of s sorted
// example:
// "eat" -> "aet"
// step 2: sorted s' is your key, hash table is a table of arrays
// unordered_map<string, string[]> H;
// H[s'].append(s);
// example: "eat" -> "aet"
// H["aet"].push("eat");
// issue: what if hash("aet") = hash("efg")
unordered_map<string, vector<string>> map;
for(string str : strs) {
string strcpy = str;
sort(strcpy.begin(),strcpy.end());
map[strcpy].push_back(str);
}
vector<vector<string>> out;
for(auto k: map) {
out.push_back(k.second);
}
return out;
}
};
First Missing Positive
Link (Hashing, Sept. 18, 2025)
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int i;
for(i = 0; i < nums.size(); i++) {
if(nums[i] <=0 or nums[i] >= nums.size()+1) nums[i] = nums.size()+1;
}
for(i=0; i < nums.size(); i++) {
if(abs(nums[i]) <= nums.size()) nums[abs(nums[i])-1] = -1*abs(nums[abs(nums[i])-1]);
}
for(i=0; i < nums.size(); i++) {
if(nums[i] > 0) {
return i+1;
}
}
return nums.size()+1;
}
};
Longest Substring Without Repeating Characters
Link (Hashing, Sept. 16, 2025)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
short int seen_char[256] {};
int max_length = 0;
short int left = 0;
short int diff = 0;
for(short int right = 0; right < s.size(); ++right) {
++diff;
if(!seen_char[s[right]]) {
++seen_char[s[right]];
max_length = (diff > max_length) ? diff : max_length;
}
else {
while(seen_char[s[right]]) {
--seen_char[s[left]];
++left;
--diff;
}
++seen_char[s[right]];
}
}
return max_length;
}
};
Longest Substring Without Repeating Characters
Link (Hashing, Sept. 11, 2025)
#include <unordered_set>
#include <math.h>
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int max_len = 0;
unordered_set<char> char_set;
auto left = s.begin();
for(auto right = s.begin(); right != s.end(); right++) {
if(char_set.count(*right) == 0) {
char_set.insert(*right);
max_len = max(max_len, static_cast<int>(right-left+1));
}
else {
while(char_set.count(*right)) {
char_set.erase(*left);
left++;
}
char_set.insert(*right);
}
}
return max_len;
}
};
Two Sum
Link (Hashing, Sept. 11, 2025)
#include <unordered_map>
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> indices{-1, -1};
unordered_map<int,int> hashmap;
for(int i = 0; i < nums.size(); i++) {
hashmap[nums[i]] = i;
}
for(int i = 0; i < nums.size(); i++) {
int y = target - nums[i];
if(hashmap[y] && hashmap[y] != i) {
indices[0] = i;
indices[1] = hashmap[y];
break;
}
}
return indices;
}
};
In-class Work
One of the primary assessments in this course is in-class work (constituting 35% of your final grade). Attending and participating in class is essential to your success in this course. The two portions of in-class work are Presentations and Discussions, and Reports.
In-class Presentations and Discussions
During each class session, students will be given problems to work on, focusing on certain topics. Students will work either individually or in groups, working on these problems (designing, implementing, and analyzing algorithms to solve these problems). After some time has passed, we will shift to a problem discussion phase.
A student or group (or groups of students) will then be asked to lead a presentation and discussion about the problem session. You will be expected to do (at a minimum) the following:
- Present the problem;
- Present your solution;
- Justify why you think your solution works;
- Analyze your solution; and
- Lead a discussion / answer questions about your solution.
Note that if you (or your group) was not able to solve the problem, that is okay! Your presentation will then be what you did to try to solve the problem, what issues you were running into, and then open the discussion to your peers to see if you can get the problem resolved.
Evaluation
This portion of class is meant to give you practice with the soft skills you need to be a successful computer scientist. As such, there is no rigid evlauation for the presentations and discussions. Giving your best effort towards solving, presenting, and discussing the problems will give you full credit. However, any half-attempts are easily identifiable and will result in point deductions. Just do your best and you will get full points.
In-class Reports
To conclude each week of class, students are expected to individually submit a report of the work done this week. This include the at least (but not limited to) following:
- Problems given in class;
- How the student and/or their group approached solving the problem;
- Challenges or insights found while solving these problems; and
- The final solution you came up with to solve the problem (if applicable).
This is not meant to be a rigorous report; it is meant to help you track your progress and help you identify your strengths and weaknesses. You might notice a pattern in the challenges you faced when trying to solve a problem, or a pattern of solving specific types of problems easily. It is in your best interest to be thorough with these reports to help you help yourself.
These reports must be submitted individually, even if you worked in groups. You are required to identify all group members and any other students you practiced with to get to your final solution. You need not acknowledge the in-class discussion in your report.
Evaluation
Reports should be 2-5 pages, save for weeks when material is sparse (e.g., the first week, Thanksgiving week, etc.). Be thorough with your report and findings, but you do not need to be overly formal.
Submissions are required to be digital and in .pdf format.
is preferred but not required.
Templates
Please find a .docx and a .tex template for your reports below.
Projects
Programming projects constitute 25% of your final grade. I expect there to be 4-6 projects throughout the semester. Your lowest project grade will be automatically dropped.
General Guidelines
Projects in this course will be in C++ unless othewise stated. You are expected to track project progress using GitHub. Projects will ask you to solve one or a series of problems, with varying difficulty.
My goal is for projects to help you focus on the concepts you are practicing in class, but also have you handle other tasks that often come with building programs (e.g., handling I/O, handling different requirements, etc.).
As such, you will often be given only a handful of files that you are expected to write in.
You can include other files (e.g., other .h and .cpp files), but do not go overboard (if you submit a project with 100 extra files when you do not need them, we are going to have a problem).
Project Submission
You will submit your projects to me in the form of a GitHub repository, where I can see any and all commits made during your project. You are expected to know how to use Git and GitHub. My general rule of thumb:
Commit early, commit often.
Project Evaluation
Each project will have a project evaluation. This evaluation occurs after you have submitted the code for your projects. It will consist of two parts.
Correctness
The first portion will evaluate the correctness of your code. I will run several tests to see if your code passes. This is purely point-based and will (most likely) be handled automatically.
Understanding
The second portion will require you (or your group) to present your program to me. You are expected to present to me how and why your program works, and expected to answer any questions I ask about your code. These evaluations will happen the week a project is submitted, and will be by appointment.
You should never be submitting code you do not understand. This is bad practice and can cause devastating issues down the line.
In the event you fail this portion of the project, you are allowed to resubmit your project within 1 week to get half credit (you are again expected to pass the “Understanding” portion of the project). If you fail again, there are no more attempts and you get a 0 for this project.
GitHub Repository for all Projects
Please see my GitHub repo for this course here. It contains the relevant information you need to setup your projects and any other code I add to the repository (e.g., adding code we did in class).
Project 1
Date Assigned: September 09, 2025.
Due Date: Wednesday, September 24th, 2025, by 11:59pm Central Time.
Project Instructions: https://github.com/alexander-r-block/uic-cs-402-fall-2025/tree/project-1/project-1#readme
Direct link to GitHub branch: https://github.com/alexander-r-block/uic-cs-402-fall-2025/tree/project-1 (this includes instructions for how to set up your repository).
Project 2
Date Assigned: October 23, 2025.
Due Date: Thursday, November 13, 2025 by 11:59pm Central Time.
Project Instructions:https://github.com/alexander-r-block/uic-cs-402-fall-2025/blob/project-2/project-2/README.md
Direct link to GitHub branch:https://github.com/alexander-r-block/uic-cs-402-fall-2025/tree/project-2/
Project 3
Date Assigned: November 22, 2025.
Due Date: Sunday, December 14, 2025 by 11:59pm Central Time.
Project Instructions:https://github.com/alexander-r-block/uic-cs-402-fall-2025/blob/project-3/project-3/README.md
Direct link to GitHub branch:https://github.com/alexander-r-block/uic-cs-402-fall-2025/tree/project-3/