Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Build confidence with an intuition-first walkthrough focused on array fundamentals.
You are given a string s of lowercase English letters and an array widths denoting how many pixels wide each lowercase English letter is. Specifically, widths[0] is the width of 'a', widths[1] is the width of 'b', and so on.
You are trying to write s across several lines, where each line is no longer than 100 pixels. Starting at the beginning of s, write as many letters on the first line such that the total width does not exceed 100 pixels. Then, from where you stopped in s, continue writing as many letters as you can on the second line. Continue this process until you have written all of s.
Return an array result of length 2 where:
result[0] is the total number of lines.result[1] is the width of the last line in pixels.Example 1:
Input: widths = [10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10], s = "abcdefghijklmnopqrstuvwxyz" Output: [3,60] Explanation: You can write s as follows: abcdefghij // 100 pixels wide klmnopqrst // 100 pixels wide uvwxyz // 60 pixels wide There are a total of 3 lines, and the last line is 60 pixels wide.
Example 2:
Input: widths = [4,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10], s = "bbbcccdddaaa" Output: [2,4] Explanation: You can write s as follows: bbbcccdddaa // 98 pixels wide a // 4 pixels wide There are a total of 2 lines, and the last line is 4 pixels wide.
Constraints:
widths.length == 262 <= widths[i] <= 101 <= s.length <= 1000s contains only lowercase English letters.Problem summary: You are given a string s of lowercase English letters and an array widths denoting how many pixels wide each lowercase English letter is. Specifically, widths[0] is the width of 'a', widths[1] is the width of 'b', and so on. You are trying to write s across several lines, where each line is no longer than 100 pixels. Starting at the beginning of s, write as many letters on the first line such that the total width does not exceed 100 pixels. Then, from where you stopped in s, continue writing as many letters as you can on the second line. Continue this process until you have written all of s. Return an array result of length 2 where: result[0] is the total number of lines. result[1] is the width of the last line in pixels.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array
[10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10] "abcdefghijklmnopqrstuvwxyz"
[4,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10] "bbbcccdddaaa"
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #806: Number of Lines To Write String
class Solution {
public int[] numberOfLines(int[] widths, String s) {
int lines = 1, last = 0;
for (int i = 0; i < s.length(); ++i) {
int w = widths[s.charAt(i) - 'a'];
if (last + w <= 100) {
last += w;
} else {
++lines;
last = w;
}
}
return new int[] {lines, last};
}
}
// Accepted solution for LeetCode #806: Number of Lines To Write String
func numberOfLines(widths []int, s string) []int {
lines, last := 1, 0
for _, c := range s {
w := widths[c-'a']
if last+w <= 100 {
last += w
} else {
lines++
last = w
}
}
return []int{lines, last}
}
# Accepted solution for LeetCode #806: Number of Lines To Write String
class Solution:
def numberOfLines(self, widths: List[int], s: str) -> List[int]:
lines, last = 1, 0
for w in map(lambda c: widths[ord(c) - ord("a")], s):
if last + w <= 100:
last += w
else:
lines += 1
last = w
return [lines, last]
// Accepted solution for LeetCode #806: Number of Lines To Write String
impl Solution {
pub fn number_of_lines(widths: Vec<i32>, s: String) -> Vec<i32> {
let mut lines = 1;
let mut last = 0;
for c in s.chars() {
let idx = ((c as u8) - b'a') as usize;
let w = widths[idx];
if last + w <= 100 {
last += w;
} else {
lines += 1;
last = w;
}
}
vec![lines, last]
}
}
// Accepted solution for LeetCode #806: Number of Lines To Write String
function numberOfLines(widths: number[], s: string): number[] {
let [lines, last] = [1, 0];
for (const c of s) {
const w = widths[c.charCodeAt(0) - 'a'.charCodeAt(0)];
if (last + w <= 100) {
last += w;
} else {
++lines;
last = w;
}
}
return [lines, last];
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.