Talentd
FleetCode
Make and follow sheets.Sign in

Number of Lines To Write String solution and explanation

EasyArrayString6 min read72.9% acceptanceUpdated 9 Apr 2026
LeetCode Number of Lines To Write String Solution Explained - JavaNick White · 5:39 · 3K viewsWatch on YouTube
9 more videos on this problem
  1. LeetCode Number of Lines To Write String Solution Explained - JavaNick White · 5:39 · 3K views
  2. Number of Lines To Write String | LeetCode 806 WalkthroughJacob Broughton · 7:58 · 734 views
  3. 806. Number of Lines To Write String || LEETCODE SOLUTION || IN C++ || DATA STRUCTURE AND ALGORITHMAbhishweta Gupta · 2:30 · 697 views
  4. 806. Number of Lines To Write String | Leetcode | PythonAbdullah Arshed · 3:54 · 526 views
  5. Leetcode solving: 806 Number of Lines To Write StringMath Geeks · 4:05 · 297 views
  6. LeetCode 806 | Number of Lines To Write String | JavaSleepy Cracker · 2:39 · 184 views
  7. Number of Lines To Write String | JAVAKnowledge Amplifier · 3:40 · 124 views
  8. my attempt at solving leetcode 806: number of lines to write string [SOLVED]Cameron Late · 18:14 · 92 views
  9. 806. Number of Lines To Write String - Javascript - Time: O(n) Space: O(1) - LeetcodeAaron Sadino Coding · 0:47 · 62 views
  10. No Sound Leetcode 806: Number of Lines To Write StringExtremeProgrammer · 1:39 · 14 views

The problem

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 == 26
  • 2 <= widths[i] <= 10
  • 1 <= s.length <= 1000
  • s contains only lowercase English letters.

Approach overview

Problem Overview: You are given an array widths where each element represents the pixel width of characters 'a' to 'z'. A string s must be written on lines with a maximum width of 100 pixels. As you place characters sequentially, once the current line exceeds the limit, you move to a new line. The task is to return the number of lines used and the width occupied by the last line.

Approach 1: Greedy Approach (O(n) time, O(1) space)

This problem naturally fits a greedy simulation. Iterate through the string once and keep a running sum representing the width used in the current line. For each character, convert it to an index using c - 'a' and fetch its width from the array. If adding this width would exceed 100, start a new line and reset the current width to that character's width. Otherwise, keep accumulating. The greedy choice works because each character must appear in order and the only decision is whether it fits in the current line or forces a new one. This linear scan makes the solution O(n) time with O(1) extra space since only counters are maintained. The logic relies on simple iteration over a string with values stored in an array.

Approach 2: Prefix Sum Approach (O(n) time, O(n) space)

A prefix sum variant first converts each character of s into its width and stores cumulative widths in a prefix array. The prefix sum at position i represents the total width of the first i characters. While scanning this structure, track when the difference between two prefix indices exceeds 100. That boundary indicates the start of a new line. This technique separates width computation from line segmentation and can help when the widths are reused or analyzed further. Building the prefix array costs O(n) time and O(n) space, and the subsequent scan is also linear.

Recommended for interviews: The greedy simulation is the expected answer. It demonstrates that you can translate constraints directly into a linear pass and maintain minimal state. Interviewers typically want to see the simple currentWidth + charWidth > 100 check and line counter update. The prefix sum variant shows familiarity with the prefix sum technique but introduces unnecessary memory for this problem.

Approach 1: Greedy Approach

In this approach, we iterate over the string and keep track of the width of the current line. When adding another character exceeds the allowed line width of 100 pixels, we start a new line. We store the total number of lines and the width of the last line.

def numberOfLines(widths, s):
    total_lines = 1
    current_width = 0

    for c in s:
        char_width = widths[ord(c) - ord('a')]
        if current_width + char_width > 100:
            total_lines += 1
            current_width = char_width
        else:
            current_width += char_width

    return [total_lines, current_width]

# Example Usage
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"
print(numberOfLines(widths, s))
import java.util.List;
import java.util.ArrayList;

public class Solution {
    public static int[] numberOfLines(int[] widths, String s) {
        int totalLines = 1;
        int currentWidth = 0;

        for (char c : s.toCharArray()) {
            int charWidth = widths[c - 'a'];
            if (currentWidth + charWidth > 100) {
                totalLines++;
                currentWidth = charWidth;
            } else {
                currentWidth += charWidth;
            }
        }

        return new int[]{totalLines, currentWidth};
    }

    public static void main(String[] args) {
        int[] 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};
        String s = "bbbcccdddaaa";
        int[] result = numberOfLines(widths, s);
        System.out.printf("[%d, %d]\n", result[0], result[1]);
    }
}
#include <vector>
#include <string>
#include <iostream>
using namespace std;

vector<int> numberOfLines(vector<int>& widths, string s) {
    int totalLines = 1;
    int currentWidth = 0;

    for (char c : s) {
        int charWidth = widths[c - 'a'];
        if (currentWidth + charWidth > 100) {
            totalLines++;
            currentWidth = charWidth;
        } else {
            currentWidth += charWidth;
        }
    }

    return {totalLines, currentWidth};
}

int main() {
    vector<int> 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};
    string s = "bbbcccdddaaa";
    vector<int> result = numberOfLines(widths, s);
    cout << "[" << result[0] << ", " << result[1] << "]" << endl;
    return 0;
}
function numberOfLines(widths, s) {
    let totalLines = 1;
    let currentWidth = 0;

    for (let i = 0; i < s.length; i++) {
        let charWidth = widths[s.charCodeAt(i) - 'a'.charCodeAt(0)];
        if (currentWidth + charWidth > 100) {
            totalLines++;
            currentWidth = charWidth;
        } else {
            currentWidth += charWidth;
        }
    }

    return [totalLines, currentWidth];
}

// Example usage
const 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];
const s = "bbbcccdddaaa";
console.log(numberOfLines(widths, s));
#include <stdio.h>

void numberOfLines(int* widths, int widthsSize, char* s, int* result) {
    int currentWidth = 0;
    int totalLines = 1;  // Start with the first line

    for (int i = 0; s[i] != '\0'; ++i) {
        int charWidth = widths[s[i] - 'a'];
        if (currentWidth + charWidth > 100) {
            totalLines++;
            currentWidth = 0;
        }
        currentWidth += charWidth;
    }

    result[0] = totalLines;
    result[1] = currentWidth;
}

int main() {
    int widths[26] = {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};
    char s[] = "bbbcccdddaaa";
    int result[2];
    numberOfLines(widths, 26, s, result);
    printf("[%d, %d]\n", result[0], result[1]);
    return 0;
}
using System;

public class Solution {
    public static int[] NumberOfLines(int[] widths, string s) {
        int totalLines = 1;
        int currentWidth = 0;

        foreach (char c in s) {
            int charWidth = widths[c - 'a'];
            if (currentWidth + charWidth > 100) {
                totalLines++;
                currentWidth = charWidth;
            } else {
                currentWidth += charWidth;
            }
        }

        return new int[] { totalLines, currentWidth };
    }

    public static void Main(string[] args) {
        int[] widths = new int[]{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};
        string s = "bbbcccdddaaa";
        int[] result = NumberOfLines(widths, s);
        Console.WriteLine($"[{result[0]}, {result[1]}]");
    }
}

For Python, the function calculates each character's width using its ASCII value and the provided widths list. It updates total_lines and current_width similarly to other solutions upon encountering a character that doesn't fit within the current line.

Complexity

The time complexity is O(n), where is the length of the string s. The space complexity is O(1).

Try this approach in the editor

Approach 2: Prefix Sum Approach

This approach takes the prefix summed widths of the string. For each new position, the difference between the prefix sums represents the total width of characters up to that position. Using this information, we determine how many characters fit into each line under the given constraints, thereby expanding calculation efficiency.

def numberOfLines(widths, s):
    total_lines = 1
    prefix_sum = [0] * (len(s) + 1)

    for i in range(len(s)):
        prefix_sum[i + 1] = prefix_sum[i] + widths[ord(s[i]) - ord('a')]

    last_valid = 0

    for i in range(1, len(s) + 1):
        if prefix_sum[i] - prefix_sum[last_valid] > 100:
            total_lines += 1
            last_valid = i - 1

    last_width = prefix_sum[len(s)] - prefix_sum[last_valid]
    return [total_lines, last_width]

# Example Usage
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"
print(numberOfLines(widths, s))
import java.util.ArrayList;
import java.util.List;

public class Solution {
    public static int[] numberOfLines(int[] widths, String s) {
        int totalLines = 1;
        int[] prefixSum = new int[s.length() + 1];
        prefixSum[0] = 0;

        for (int i = 0; i < s.length(); ++i) {
            prefixSum[i + 1] = prefixSum[i] + widths[s.charAt(i) - 'a'];
        }

        int lastValid = 0;
        for (int i = 1; i <= s.length(); ++i) {
            if (prefixSum[i] - prefixSum[lastValid] > 100) {
                totalLines++;
                lastValid = i - 1;
            }
        }
        return new int[]{totalLines, prefixSum[s.length()] - prefixSum[lastValid]};
    }

    public static void main(String[] args) {
        int[] 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};
        String s = "bbbcccdddaaa";
        int[] result = numberOfLines(widths, s);
        System.out.printf("[%d, %d]\n", result[0], result[1]);
    }
}
#include <iostream>
#include <vector>
using namespace std;

vector<int> numberOfLines(vector<int>& widths, string s) {
    int totalLines = 1;
    vector<int> prefixSum(s.size() + 1);
    prefixSum[0] = 0;

    for (int i = 0; i < s.size(); ++i) {
        prefixSum[i + 1] = prefixSum[i] + widths[s[i] - 'a'];
    }

    int lastWidth = 0;
    for (int i = 1; i <= s.size(); ++i) {
        if (prefixSum[i] - prefixSum[lastWidth] > 100) {
            totalLines++;
            lastWidth = i - 1;
        }
    }

    return {totalLines, prefixSum[s.size()] - prefixSum[lastWidth]};
}

int main() {
    vector<int> 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};
    string s = "bbbcccdddaaa";
    vector<int> result = numberOfLines(widths, s);
    cout << "[" << result[0] << ", " << result[1] << "]" << endl;
    return 0;
}
function numberOfLines(widths, s) {
    let totalLines = 1;
    let prefixSum = new Array(s.length + 1).fill(0);

    for (let i = 0; i < s.length; ++i) {
        prefixSum[i + 1] = prefixSum[i] + widths[s.charCodeAt(i) - 'a'.charCodeAt(0)];
    }

    let lastValid = 0;
    for (let i = 1; i <= s.length; ++i) {
        if (prefixSum[i] - prefixSum[lastValid] > 100) {
            totalLines++;
            lastValid = i - 1;
        }
    }

    let lastWidth = prefixSum[s.length] - prefixSum[lastValid];
    return [totalLines, lastWidth];
}

// Example usage
const 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];
const s = "bbbcccdddaaa";
console.log(numberOfLines(widths, s));
#include <stdio.h>
#include <string.h>

void numberOfLines(int* widths, int widthsSize, char* s, int* result) {
    int totalLines = 1, currentWidth = 0;
    int prefixSum[strlen(s) + 1];
    prefixSum[0] = 0;

    for (int i = 0; s[i] != '\0'; ++i) {
        prefixSum[i + 1] = prefixSum[i] + widths[s[i] - 'a'];
    }

    for (int i = 0; s[i] != '\0'; ++i) {
        int nextWidth = prefixSum[i + 1] - prefixSum[currentWidth];
        if (nextWidth > 100) {
            totalLines++;
            currentWidth = i;
        }
    }
    result[0] = totalLines;
    result[1] = prefixSum[strlen(s)] - prefixSum[currentWidth];
}

int main() {
    int widths[26] = {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};
    char s[] = "bbbcccdddaaa";
    int result[2];
    numberOfLines(widths, 26, s, result);
    printf("[%d, %d]\n", result[0], result[1]);
    return 0;
}
using System;

public class Solution {
    public static int[] NumberOfLines(int[] widths, string s) {
        int totalLines = 1;
        int[] prefixSum = new int[s.Length + 1];

        for (int i = 0; i < s.Length; ++i) {
            prefixSum[i + 1] = prefixSum[i] + widths[s[i] - 'a'];
        }

        int lastValid = 0;

        for (int i = 1; i <= s.Length; ++i) {
            if (prefixSum[i] - prefixSum[lastValid] > 100) {
                totalLines++;
                lastValid = i - 1;
            }
        }

        int lastWidth = prefixSum[s.Length] - prefixSum[lastValid];
        return new int[] { totalLines, lastWidth };
    }

    public static void Main(string[] args) {
        int[] widths = new int[]{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};
        string s = "bbbcccdddaaa";
        int[] result = NumberOfLines(widths, s);
        Console.WriteLine($"[{result[0]}, {result[1]}]");
    }
}

In Python, the prefix sum list is built and used to check when new lines should begin. The technique identifies when accumulated width measurements overstep the 100-pixel limit, thus dictating consecutive line increments for line counting accordingly.

Complexity

The time complexity is O(n) for prefix summation. The space complexity is O(n) given the size of the prefix sum list.

Try this approach in the editor

Approach 3: Simulation

We define two variables lines and last, representing the number of lines and the width of the last line, respectively. Initially, lines = 1 and last = 0.

We iterate through the string s. For each character c, we calculate its width w. If last + w leq 100, we add w to last. Otherwise, we increment lines by one and reset last to w.

Finally, we return an array consisting of lines and last.

The time complexity is O(n), where n is the length of the string s. The space complexity is O(1).

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];
}
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}
}
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]
    }
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Greedy Approach

The time complexity is O(n), where is the length of the string s. The space complexity is O(1).

Prefix Sum Approach

The time complexity is O(n) for prefix summation. The space complexity is O(n) given the size of the prefix sum list.

Simulation–

Complexity analysis

ApproachTimeSpaceWhen to Use
Greedy SimulationO(n)O(1)Best general solution. Simple single pass through the string with constant memory.
Prefix SumO(n)O(n)Useful when cumulative widths are needed for additional analysis or repeated queries.

Frequently asked questions

Is Number of Lines To Write String easy or hard?

LeetCode classifies this problem as Easy with an acceptance rate above 70%. The challenge is mainly careful simulation and handling the width reset correctly when a new line starts.

Number of Lines To Write String Python/Java solution

The implementation is straightforward in Python, Java, C++, or JavaScript. Map each character to its width using the index c - 'a', track the current line width, and increment the line count whenever the limit of 100 pixels is exceeded.

How to solve Number of Lines To Write String in O(n)?

Scan the string once and track the width used in the current line. For each character, look up its width from the 26‑element array. If currentWidth + charWidth exceeds 100, increment the line counter and reset the width to that character; otherwise continue accumulating.

What is the best approach for Number of Lines To Write String?

The greedy simulation is the best approach. Iterate through the string, keep a running width for the current line, and start a new line whenever adding the next character exceeds 100 pixels. This solution runs in O(n) time with O(1) extra space.

Is Number of Lines To Write String asked at Google/Amazon/Meta?

Problems of this style appear frequently in screening rounds at companies like Amazon and Google because they test careful simulation and edge‑case handling. The task evaluates whether candidates can translate constraints into a clean linear pass.

What data structure is used in Number of Lines To Write String?

The solution primarily uses an array for character widths and simple counters while iterating through the string. Some variations also use prefix sum arrays to store cumulative widths, though this is not required for the optimal solution.

What is the time complexity of Number of Lines To Write String?

The optimal solution runs in O(n) time where n is the length of the string. Each character is processed exactly once to check whether it fits in the current line or requires starting a new one. Space complexity is O(1).

Comments

Now write it yourselfClose this page and solve Number of Lines To Write String in the editor, without looking.
Practise Number of Lines To Write String