经典算法实例分析:写字符串需要的行数

📅 2026/7/6 8:04:54
经典算法实例分析:写字符串需要的行数
我们先来看题目描述我们要把给定的字符串 S 从左到右写到每一行上每一行的最大宽度为 100 个单位如果我们在写某个字母的时候会使这行超过了 100 个单位那么我们应该把这个字母写到下一行。我们给定了一个数组 widths 这个数组 widths [0] 代表 a 需要的单位widths [1] 代表 b 需要的单位... widths [25] 代表 z 需要的单位。现在回答两个问题至少多少行能放下 S 以及最后一行使用的宽度是多少个单位将你的答案作为长度为 2 的整数列表返回。示例 1输入: 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 输出: [3, 60] 解释: 所有的字符拥有相同的占用单位10。所以书写所有的26个字母 我们需要2个整行和占用60个单位的一行。示例 2输入: 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 输出: [2, 4] 解释: 除去字母a所有的字符都是相同的单位10并且字符串 bbbcccdddaa 将会覆盖 9 * 10 2 * 4 98 个单位. 最后一个字母 a 将会被写到第二行因为第一行只剩下2个单位了。 所以这个答案是2行第二行有4个单位宽度。注:字符串 S 的长度在 [1, 1000] 的范围。S 只包含小写字母。widths 是长度为 26 的数组。widths [i] 值的范围在 [2, 10] 。解决方案方法一直接遍历思路与算法我们从左到右遍历字符串 s 中的每个字母lines 表示当前书写所需的行数width 表示当前行已经使用的宽度。当遍历到一个字母 c 时如果 width widths [c] ≤ 100 此时那么更新 width width widths [c] 并保持 lines 不变如果 width widths [c] 100 此时需要另起新的一行那么此时 lines 的值加 1 并将 width 置为 widths [c] 。代码Python3class Solution: def numberOfLines(self, widths: List[int], s: str) - List[int]: MAX_WIDTH 100 lines, width 1, 0 for c in s: need widths[ord(c) - ord(a)] width need if width MAX_WIDTH: lines 1 width need return [lines, width]Javaclass Solution { public static final int MAX_WIDTH 100; public int[] numberOfLines(int[] widths, String s) { int lines 1; int width 0; for (int i 0; i s.length(); i) { int need widths[s.charAt(i) - a]; width need; if (width MAX_WIDTH) { lines; width need; } } return new int[]{lines, width}; } }Cconst int MAX_WIDTH 100; class Solution { public: vectorint numberOfLines(vectorint widths, string s) { int lines 1; int width 0; for (auto c : s) { int need widths[c - a]; width need; if (width MAX_WIDTH) { lines; width need; } } return {lines, width}; } };复杂度分析时间复杂度O(n) 其中 n 为字符串 s 的长度。需要遍历一遍字符串 s 求出行数。空间复杂度O(1) 。