You are given a string text
that represents a sentence, an array fonts
of available font sizes (integers, sorted in descending order), and a 2D array fontInfo
. Each entry in fontInfo
is an array of 3 integers: [fontSize, widthPerChar, height]
, describing the width of each character and height for that font size. You are also given two integers w
and h
, representing the width and height of a screen in pixels.
Your task is to find the maximum font size from fonts
that allows the entire text
to fit inside the screen, meaning:
w
.h
.
If no font size fits, return -1
. You are guaranteed that fonts
contains only unique font sizes and fontInfo
contains information for all font sizes in fonts
.
The core challenge is to find the largest font size that fits both width and height constraints. A brute-force approach would be to try each font size from largest to smallest, check if the sentence fits, and return the first valid size. This is feasible because the number of fonts is usually small.
However, we can optimize further. Since fonts
is sorted in descending order, we can use binary search to quickly find the maximum valid font size. This reduces unnecessary checks and speeds up the process.
The main steps are:
Let's break down the solution step by step:
[widthPerChar, height]
using a hash map (dictionary). This allows O(1) lookup for each font's info.fonts
is sorted in descending order, we can perform binary search to find the largest font size that fits.totalWidth = len(text) × widthPerChar
height
(from font info)totalWidth ≤ w
and height ≤ h
, this font fits.-1
.This method is efficient because:
Suppose text = "leetcode"
, fonts = [28,24,20,18,14,10]
, fontInfo = [[28,2,4],[24,2,3],[20,1,3],[18,1,2],[14,1,2],[10,1,1]]
, w = 50
, h = 6
.
If the screen was smaller (e.g., w=10
), none of the larger fonts would fit, and the binary search would continue to lower values until either a fit is found or -1 is returned.
Brute-force approach:
The problem asks for the largest font size that allows a sentence to fit within given screen dimensions. By mapping font sizes to their properties and using binary search, we efficiently find the optimal solution. The key insight is leveraging the sorted font sizes and using hash maps for quick lookups, making the solution both simple and fast.
class Solution:
def maxFont(self, text, fonts, fontInfo, w, h):
# Build font info dictionary: font size -> (width per char, height)
font_map = {size: (width, height) for size, width, height in fontInfo}
left, right = 0, len(fonts) - 1
res = -1
while left <= right:
mid = (left + right) // 2
font_size = fonts[mid]
width, height = font_map[font_size]
total_width = len(text) * width
if total_width <= w and height <= h:
res = font_size
left = mid + 1
else:
right = mid - 1
return res
class Solution {
public:
int maxFont(string text, vector<int>& fonts, vector<vector<int>>& fontInfo, int w, int h) {
unordered_map<int, pair<int, int>> fontMap;
for (auto& info : fontInfo) {
fontMap[info[0]] = {info[1], info[2]};
}
int left = 0, right = fonts.size() - 1, res = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
int fontSize = fonts[mid];
int width = fontMap[fontSize].first;
int height = fontMap[fontSize].second;
int totalWidth = text.size() * width;
if (totalWidth <= w && height <= h) {
res = fontSize;
left = mid + 1;
} else {
right = mid - 1;
}
}
return res;
}
};
class Solution {
public int maxFont(String text, int[] fonts, int[][] fontInfo, int w, int h) {
Map<Integer, int[]> fontMap = new HashMap<>();
for (int[] info : fontInfo) {
fontMap.put(info[0], new int[]{info[1], info[2]});
}
int left = 0, right = fonts.length - 1, res = -1;
while (left <= right) {
int mid = (left + right) / 2;
int fontSize = fonts[mid];
int[] info = fontMap.get(fontSize);
int totalWidth = text.length() * info[0];
if (totalWidth <= w && info[1] <= h) {
res = fontSize;
left = mid + 1;
} else {
right = mid - 1;
}
}
return res;
}
}
var maxFont = function(text, fonts, fontInfo, w, h) {
const fontMap = new Map();
for (const [size, width, height] of fontInfo) {
fontMap.set(size, [width, height]);
}
let left = 0, right = fonts.length - 1, res = -1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
const fontSize = fonts[mid];
const [width, height] = fontMap.get(fontSize);
const totalWidth = text.length * width;
if (totalWidth <= w && height <= h) {
res = fontSize;
left = mid + 1;
} else {
right = mid - 1;
}
}
return res;
};