Understanding the problem first
On This Lesson 11 topics
Lesson Overview
You now know how to write programs with variables, decisions, loops, methods, arrays, and strings. This module teaches the skill that sits in front of all of them: working out what to build before you type any Java.
The analogy for the whole module is planning a trip with a map before you start driving. If you drive first and look at the map later, you may move quickly, but you may also be going the wrong way. In this lesson you will learn the first part of the map: restating a problem in your own words, naming its inputs, outputs, and constraints, working one small example by hand, and asking questions about anything unclear.
Why this matters: a program that runs without errors can still solve the wrong problem. The compiler checks syntax, not whether you understood the request. A misunderstanding found before coding costs a conversation; found after release it costs much more.
The next lesson, "Decomposition", shows how to split an understood problem into small steps.
Learning Objectives
By the end of this lesson you will be able to:
- Restate a problem in your own words and compare your version with the original.
- Identify the inputs, outputs, and constraints of a problem.
- Spot vague words in a problem statement and turn them into precise questions.
- Work one small example by hand and use it to check your understanding.
- Explain why coding before understanding wastes time.
Written Explanation
Coding before understanding
A very common beginner habit is to read the first line of a problem, think "I know how to do that", and start typing. Sometimes it works. Often the first idea solves an easier problem than the one that was asked, and the mistake only shows up after a lot of code exists.
If you type from the first idea, you fix bugs in code that may not be the right code. If you spend a few minutes understanding first, you write less code, and it is more likely to be the right code. Those minutes are the cheapest of the whole task.
Step 1: restate the problem
Say the problem again in your own words, as if explaining it to a friend who has not read it. If you cannot do this, you do not yet understand it. If your version differs from the original, you have found a question to ask.
Take the statement "find the second largest number". A restatement might be: "I receive some whole numbers, and I must give back the one that comes right below the biggest." Writing it out already raises doubts. What if the biggest number appears twice? That is a question, and we will come back to it.
Step 2: name inputs, outputs, and constraints
Every programming problem can be described with three parts.
- Inputs are what you are given: the data that comes in. Name its type and its shape (a single value, an array, a line of text).
- Outputs are what you must produce: the result, its type, and where it goes (returned from a method, printed, and so on).
- Constraints are the rules and limits: how many values there can be, what values are allowed, what must never happen, and what should happen in unusual situations.
For "find the second largest number":
| Part | Answer |
|---|---|
| Input | An array of int values |
| Output | One int: the second largest value |
| Constraints | At least how many values? Can values repeat? What if there are not enough values? |
Notice that the constraints row is mostly questions. That is normal. Constraints are where problem statements are usually silent, and silence is where bugs hide.
Step 3: find the vague words
Problem statements written in everyday language are full of words that sound clear and are not. Look out for these:
- Quantity words such as "some", "many", or "a few": how many, at minimum and maximum?
- Ranking words such as "largest", "best", or "first": what happens in a tie?
- Fuzzy words such as "valid", "loyal", or "short": by what exact rule?
- Missing cases: what should happen when there is no answer?
Each vague word becomes a question. Sometimes nobody is available to answer. Then make a reasonable decision and write it down as an assumption. A written assumption can be corrected later; a hidden one becomes a bug.
Step 4: work one example by hand
Pick a small, concrete example and solve it yourself, with no code, as a person would. For [4, 9, 7], the largest is 9 and the second largest is 7. This does two jobs:
- It proves that you understand what "correct" looks like for at least one case.
- It becomes your first test. When you write code later, this is the first thing you will run.
Then try a second example that is a bit unusual, such as [9, 9, 7]. Doing it by hand forces the tie question into the open: is the answer 9 (the second value in sorted order) or 7 (the second different value)? You cannot code the answer until you decide.
Step 5: ask questions, then record decisions
Turn your doubts into short, specific questions, and write the answers beside the problem. A question is good when it can be answered in a few words. "What should happen for an empty list?" is good. "Can you explain the problem again?" is not.
Here is a compact way to keep the result, which you can use for every problem in this module:
Problem (my words): ...
Input: ...
Output: ...
Constraints: ...
Questions/decisions: ...
Example by hand: ...This takes a few minutes and it is the document that the rest of the module builds on.
Examples
Example 1: second largest (simple)
Statement: "Find the second largest number."
Problem (my words): Given whole numbers, return the one just below the biggest.
Input: int[] values
Output: one int
Constraints: at least 2 values? repeats allowed?
Questions/decisions: [9, 9, 7]: is the answer 9 or 7?
Decision: ask. If nobody can answer, assume 7 ("second distinct").
Example by hand: [4, 9, 7] -> 7Why does the decision matter? This quick solution sorts a copy of the array and takes the second value from the end:
import java.util.Arrays;
public class SecondLargest {
static int secondBySorting(int[] a) {
int[] copy = Arrays.copyOf(a, a.length);
Arrays.sort(copy);
return copy[copy.length - 2];
}
public static void main(String[] args) {
System.out.println(secondBySorting(new int[]{4, 9, 7}));
System.out.println(secondBySorting(new int[]{9, 9, 7}));
System.out.println(secondBySorting(new int[]{5}));
}
}Output from running it:
7
9
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 1
at SecondLargest.secondBySorting(SecondLargest.java:6)
at SecondLargest.main(SecondLargest.java:11)(The class name in the stack trace depends on the file name you choose.) The code is correct for the first example, answers 9 for [9, 9, 7] (which is right only if "second largest" means "second in sorted order"), and crashes for a single value. Three results, three different lessons about the problem, and no line of the code was "wrong" in the sense the compiler checks.
Example 2: a late fee for a library book (practical)
Statement: "Charge a late fee when a book is returned late."
Start by finding the vague words: "late", "fee", and the missing cases.
Problem (my words): Given how many days a book was kept and how long the loan is,
work out how much the borrower owes.
Input: days kept (int), loan length in days (int)
Output: fee in cents (int), printed or returned
Constraints: What is the fee per late day? Is there a maximum fee?
Is the due day itself late? Can days kept be 0 or negative?
Questions/decisions: Ask the library. Suppose the answers are: 50 cents per late day,
maximum 500 cents, the due day is not late.
Example by hand: loan 14 days, kept 17 days -> 3 late days -> 150 cents
Second example: loan 14 days, kept 14 days -> 0 late days -> 0 cents"The due day is not late" is a decision about a boundary, exactly where an if is often written with > instead of >=. No code exists yet, and the hardest question is already answered. The two hand examples are your first two tests: 150 and 0.
Example 3: a username check (realistic)
Statement from a product manager: "Usernames must be valid."
This statement is almost empty. A backend developer does not start coding. They restate it and ask.
Problem (my words): Given the text a user typed, decide if it can be accepted as a username.
Input: String candidate
Output: boolean (true if accepted)
Constraints: Minimum and maximum length? Allowed characters? Are spaces at the
ends removed first? Is "Sam" the same as "sam"?
Questions/decisions: Answers received: 3 to 12 characters, letters and digits only,
spaces at the ends are removed before checking.
Example by hand: "sam12" -> true. " ab " -> after trimming "ab" is 2 characters -> false.Three answers turned "valid" into rules anyone can check, and the second hand example tests a constraint (trimming) that would be forgotten if you coded from the word "valid". This is the habit that later becomes requirements clarification.
Backend Insight
In backend work, problem statements usually come from other people: a product owner, a client, another team. They describe a wish, not a specification. A request such as "send customers a discount" hides many decisions: which customers, how much, when, what if they already have a discount, what is logged.
The inputs, outputs, and constraints routine is the same one used for real services. A backend method has inputs (a request), outputs (a response), and constraints (business rules, allowed values, limits). Teams that skip this step ship code that matches the wording of a ticket but not what the business needed, and they find out from unhappy users.
Written decisions matter too: "the due day is not late" recorded next to the code tells the next reader it was a choice, not an accident.
Common Mistakes
Mistake 1: Coding before understanding
- Incorrect: reading "find the second largest" and typing a loop at once.
- Correct: restating the problem, asking about ties and short arrays, and doing an example by hand first.
Why it happens: typing feels like progress, and thinking feels like delay. How to avoid it: do not open the editor until the restatement and the first hand example are written down.
Mistake 2: Leaving constraints empty
A blank constraints line usually means "I did not think about it", not "there are none". Fill the line with questions even if you cannot answer them yet.
Mistake 3: Mixing up the problem and the solution
- Incorrect: "The input is a sorted array." (The statement never said so; this is a hidden plan.)
- Correct: "The input is an array in any order." (Only what the problem states.)
If your description of the inputs already contains your solution idea, check whether the problem really promised it.
Mistake 4: Silent assumptions
An assumption you never write down is invisible, even to you next week. Keep it beside the rest of your restatement.
Exercises
Try each exercise yourself before opening the solutions. Write your answers in your own words.
Level A: Foundation
A1. Name the three parts used to describe any problem before coding, and give one sentence about each.
Show solution A1
A1. Inputs: the data that comes in, with its type and shape. Outputs: the result to produce, with its type and where it goes. Constraints: the rules and limits, such as sizes, allowed values, and what to do in unusual cases.
A2. For the problem "count the vowels in a word", write the input and the output, including their Java types.
Show solution A2
A2. Input: a String (the word). Output: an int (the number of vowels). A good answer would also ask: are uppercase letters counted, and is y a vowel?
A3. Underline the vague words in this statement: "Show the best few products on the home page." List them.
Show solution A3
A3. Vague words: "best" (by sales? by rating?), "few" (how many exactly?), "products" (all, or only those in stock?), and the missing case of what to show if there are fewer products than requested.
Level B: Application
B1. For the problem "check whether a year is a leap year", write a full restatement using the template from the lesson: problem in your words, input, output, constraints as questions, and one example by hand.
Show solution B1
B1.
Problem (my words): Given a year, say whether it has 366 days.
Input: int year
Output: boolean
Constraints: Years before 1? Which calendar rules (every 4 years, but not 100,
except 400)?
Example by hand: 2024 -> true; 1900 -> false; 2000 -> true; 2023 -> falseThe key point is that the template exposes the "100 and 400" rule before any code exists.
B2. The statement is "Give a student a pass if they did well." Write four questions that would make it precise, and for each, say what it would change in the code.
Show solution B2
B2. Sample questions: What counts as "did well", a minimum mark (changes the number in the comparison)? Is the minimum mark itself a pass (changes > to >=)? Is there more than one exam to combine (changes the input from one number to an array)? What happens to invalid marks such as 120 (adds a validity check)? Other reasonable questions are accepted.
B3. A teammate writes "Input: a sorted array" for the problem "find the smallest number in an array", but the statement never mentioned sorting. Explain what is wrong, and rewrite the input line.
Show solution B3
B3. The input line describes a solution idea (using sorting) that the problem never promised, so the code might break on unsorted data. Correct line: "Input: an array of int values in any order."
Level C: Challenge
C1. Problem: "Print the median of three numbers." Write the full restatement. Include at least two unusual examples solved by hand, and decide what a tie such as 5, 5, 9 should give.
Show solution C1
C1.
Problem (my words): Given three numbers, return the middle one when they are in order.
Input: three ints (a, b, c)
Output: one int
Constraints: Can values repeat? Are negatives allowed?
Examples by hand: (3, 1, 2) -> 2; (5, 5, 9) -> 5; (-4, -4, -4) -> -4
Decision: With repeated values, the median is still the middle value in sorted
order, so (5, 5, 9) gives 5.C2. The statement says "Return the first repeated number in an array." Find at least two meanings of "first repeated" that give different answers on [3, 1, 2, 1, 3], and show each answer.
Show solution C2
C2. Meaning 1: the value whose second occurrence appears earliest in the array. In [3, 1, 2, 1, 3] the second 1 (index 3) comes before the second 3 (index 4), so the answer is 1. Meaning 2: the value that appears earliest and also appears again later. The first element 3 appears again later, so the answer is 3. Both meanings are reasonable, which is why the question must be asked.
Mini Challenge
Take this statement: "Given a list of prices, work out the total with the shop discount."
- Restate the problem in your own words.
- Write the input, output, and at least four constraints as questions.
- Make an assumption for each question and write it down.
- Solve one example by hand with your assumptions, and one unusual example.
Check your work: every vague word has a question, every assumption is written, and your two examples have clear expected results.
Summary & Next Lesson
Key takeaways
- Coding before understanding is driving without knowing the destination.
- Restate the problem in your own words. If you cannot, you do not understand it yet.
- Describe every problem with inputs, outputs, and constraints. Constraints are mostly questions at first.
- Vague words (quantities, rankings, fuzzy rules, missing cases) become questions. Unanswered questions become written assumptions.
- Solve one small example by hand, plus one unusual one. They become your first tests.
Next lesson
You can now say exactly what a problem asks. The next lesson, "Decomposition", shows how to break a clear but large problem into small steps that you can solve one at a time.
Self-check
- Which three things should you identify first in any problem?
- Why is a blank "constraints" line a warning sign?
- What should you do with a question nobody can answer?
- Why do we solve an example by hand before coding?
- "Find the best student" contains a vague word. Which one, and what questions does it raise?
Show answers
- Inputs, outputs, and constraints.
- It usually means constraints were not thought about, not that there are none. Unknown constraints are where bugs hide.
- Make a reasonable decision and write it down as an assumption, so it can be reviewed and corrected.
- It proves you know what a correct answer looks like, and it becomes the first test of the code.
- "Best": by which measure (average mark, one exam, attendance), and what happens in a tie or when there are no students.
References
- Oracle, Java SE 21 API:
String. Supports the behaviour oftrim()used in the username example (it removes characters up to the space character at both ends). - The Java code in this lesson was compiled and run with JDK 21; the output shown is real output from that run. The "restate, inputs/outputs/constraints" routine is a standard teaching practice; I did not cite one specific source for it.
Practice
Apply this lesson with the module's lab, exercises and quiz.
Marking a lesson complete is optional and you can undo it any time. Your progress stays in this browser.