Asked 4 months ago
0Comments
2 Views
Given a string s
and an integer numRows
, we need to write the string in a zigzag pattern and then read it line by line.
For example, the string "PAYPALISHIRING" with 3 rows would be written like this:
P A H N
A P L S I I G
Y I R
Reading line by line gives us "PAHNAPLSIIGYIR".
Check for Edge Case:
numRows
is 1, the zigzag pattern is just the string itself since there's only one row.Create Storage for Each Row:
numRows
elements.Initialize Variables:
i
: to iterate through each character in the input string s
.row
: to keep track of the current row we are filling.direction
: to keep track of the direction (down or up). True means going down, and false means going up.Fill the Rows in a Zigzag Manner:
s
.Concatenate All Rows:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
string convert(string s, int numRows) {
// Edge case: If numRows is 1, return the original string
if (numRows == 1)
return s;
// Create a vector of strings to store the zigzag pattern for each row
vector<string> zigzag(numRows);
// Initialize variables
int i = 0, row = 0;
bool direction = 1; // True for down, False for up
// Loop through each character in the string
while (true) {
// Moving down the rows
if (direction) {
while (row < numRows && i < s.size()) {
zigzag[row++].push_back(s[i++]);
}
row = numRows - 2; // Prepare to move up (second last row)
} else { // Moving up the rows
while (row >= 0 && i < s.size()) {
zigzag[row--].push_back(s[i++]);
}
row = 1; // Prepare to move down (second row)
}
// If all characters are processed, break the loop
if (i >= s.size())
break;
// Change direction
direction = !direction;
}
// Concatenate all rows to form the final string
string ans = "";
for (i = 0; i < zigzag.size(); i++) {
ans += zigzag[i];
}
return ans;
}
int main() {
string s = "PAYPALISHIRING";
int numRows = 3;
string result = convert(s, numRows);
cout << result << " ";
return 0;
}
Approach:
row = numRows - 2;
This line is setting up the starting position for the upward diagonal movement. Let's visualize why:
For numRows = 4:
0 P I N
1 A L S I
2 Y A H R
3 P I
When we finish the downward movement, we're at row 3 (index 3). To start the upward diagonal, we need to move one step up, which is why we use numRows - 2
. This puts us at row 2 (index 2), ready to start the diagonal upward movement.
zigzag[row++].push_back(s[i++]);
This line is doing three things at once: a. Adding a character to the current row b. Moving to the next row c. Moving to the next character in the input stringLet's break it down:
zigzag[row]
: This selects the current row in our 2D structure..push_back(s[i])
: This adds the current character from the input string to the end of the current row.row++
: This increments the row index, moving us to the next row.i++
: This increments the index in the input string, moving us to the next character.The movement:
When going top to bottom:
0 P
1 A
2 Y
3 P
We start at row 0 and keep adding characters and moving down until we hit the bottom.
When going bottom to top (diagonally):
0 P I
1 A L
2 Y A
3 P
We start at row 2 (numRows - 2) and keep adding characters and moving up diagonally until we hit the top.
The key to understanding the column movement is realizing that we're not explicitly moving columns. Instead, we're just adding characters to each row string. The column structure emerges naturally from this process.
In the downward movement, each character goes into a new row, creating the vertical part of the zigzag.
In the upward movement, each character goes into the next row up, but because we've moved to a new position in the string, it appears in what we visualize as the next column.
This approach cleverly creates the zigzag pattern without needing to manually manage column positions. The pattern emerges from the alternating down and up movements, and how we add characters to each row string.
Does this help clarify the movement and how we're creating the zigzag pattern?
Share