Problem overview
The method printX receives a positive integer n and prints an n by n picture of the letter X. Every line has exactly n characters. Each character is x if it lies on one of the two diagonals and - otherwise. The method prints the lines with console.log and returns nothing.
For n = 5 the output is:
x---x
-x-x-
--x--
-x-x-
x---x
The first line has its x's at the two ends, positions 0 and 4. Each following line has them one step closer to the middle. On the third line the two positions meet at 2, so that line holds a single x.
Approach: track two column positions
You don't need to search the grid for diagonal cells. On line i (counting from 0), the main diagonal crosses column i and the other diagonal crosses column n - 1 - i. So every line is fully described by two numbers, and those numbers change in a simple way from one line to the next: the first goes up by 1 and the second goes down by 1.
That suggests two variables, firstX and secondX, starting at 0 and n - 1. The program prints one line, then moves both variables one step inward. Building a single line from those two numbers is a separate small job, so the lesson puts it in its own helper, buildString.
Step by step
- Declare the two positions. Both are numbers declared on one line. They start at the two ends of the first line.
- Loop once per line. A
forloop with an indexifrom 0 whilei < ngives exactlynlines. The index is not used inside the loop body, because the two position variables carry all the information. - Build and print the line. Pretend
buildStringalready exists. It takesnand the two positions and returns the line as a string. Inside a class, a method is reached throughthis, so the call isthis.buildString(...). - Move the x's inward. After printing,
firstXgoes up by 1 andsecondXgoes down by 1, ready for the next line. - Write the helper's signature. It sits in the same class and matches the call: three
numberparameters and astringreturn type. - Start with an empty string. The helper collects the characters of one line in
str. - Loop over the columns. Another
forloop runs from 0 whilei < n, one iteration per character. - Choose the character. If
iequalsfirstXorsecondX, append"x". Otherwise append"-". - Return after the loop. Returning inside the loop would stop after the first character.
The solution in TypeScript
class Solution {
printX(n: number): void {
let firstX: number = 0, secondX: number = n - 1;
for (let i: number = 0; i < n; i++) {
const str: string = this.buildString(n, firstX, secondX);
console.log(str);
firstX++;
secondX--;
}
}
buildString(n: number, firstX: number, secondX: number): string {
let str: string = '';
for (let i: number = 0; i < n; i++) {
if (i === firstX || i === secondX) {
str += "x";
} else {
str += "-";
}
}
return str;
}
}
Some TypeScript details in this code:
- The annotations are documentation for the compiler.
let firstX: numberwould work the same without: number, because TypeScript infers the type from the initial value. The annotations disappear when the code is compiled to JavaScript. - One
let, two variables.let firstX: number = 0, secondX: number = n - 1;declares both, and each one carries its own annotation. constforstrinprintX. The line is never reassigned, soconstfits. InbuildString,strgrows with+=, so it must belet.===. Strict equality compares without converting types. For numbers it is the right default.- Strings are immutable.
str += "x"creates a new string and stores it back instr. For a line of a few dozen characters that is fine. this.is required. A barebuildString(...)inside a method looks for a variable or function of that name, not a method of the class.
Complexity
Time: O(n²). printX runs n iterations, and each calls buildString, which does n iterations of its own. The output itself has n * n characters, so no approach that prints them all can do better.
Space: O(n). Only one line is held in memory at a time, and the previous line is discarded when the next one is built.
Edge cases and common mistakes
n = 1. Both positions are 0, so the output is the single linex.- Even
n. Forn = 4the x's never meet at one column: the middle two lines each have the x's at positions 1 and 2, so they look like-xx-. The output is:
x--x
-xx-
-xx-
x--x
- Odd
n. On the middle line the two positions are equal, so the condition matches once and the line has onex. - Starting at 1 and
n. Positions in the string are counted from 0. StartingfirstXat 1 andsecondXatnpushes the picture one column to the right, andsecondXwould never match. - Moving the positions before printing. The first line would already be shifted inward, and the picture would be wrong from the top.
- Forgetting to move one of the variables. If
secondXstayed atn - 1, the right-hand x would stay on the last column on every line. - Printing characters one at a time.
console.logalways ends the line it prints. To print a whole line you have to build the string first, which is what the helper does.
Testing
n = 5prints the picture at the top.n = 4prints the four lines above.n = 1printsx.n = 2printsxxtwice, because both positions fill the two columns.- Calling
buildString(5, 1, 3)returns-x-x-.