You are given a string text. We want to display text on a screen of width
w and height h. You can choose any font size from array fonts, which
contains the available font sizes in ascending order.
You can use the FontInfo interface to get the width and height of any
character at any available font size.
The FontInfo interface is defined as such:
1
2
3
4
5
6
7
8
9
interfaceFontInfo {
// Returns the width of character ch on the screen using font size fontSize.// O(1) per callpublicintgetWidth(int fontSize, char ch);
// Returns the height of any character on the screen using font size fontSize.// O(1) per callpublicintgetHeight(int fontSize);
}
The calculated width of text for some fontSize is the sum of every
getWidth(fontSize, text[i]) call for each 0 <= i < text.length
(0-indexed). The calculated height of text for some fontSize is
getHeight(fontSize). Note that text is displayed on a single line.
It is guaranteed that FontInfo will return the same value if you call
getHeight or getWidth with the same parameters.
It is also guaranteed that for any font size fontSize and any character
ch:
We want the largest font size such that the text fits within the given width and height. Since the font sizes are sorted, we can use binary search to efficiently find the maximum valid font size by querying the FontInfo API for width and height.
classSolution {
publicintmaxFont(String text, int w, int h, int[] fonts, FontInfo fontInfo) {
int l = 0, r = fonts.length- 1, ans =-1;
while (l <= r) {
int m = (l + r) / 2;
int fontSize = fonts[m];
if (fontInfo.getHeight(fontSize) > h) {
r = m - 1;
continue;
}
int width = 0;
for (char c : text.toCharArray()) {
width += fontInfo.getWidth(fontSize, c);
}
if (width <= w) {
ans = fontSize;
l = m + 1;
} else {
r = m - 1;
}
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution:
defmaxFont(self, text: str, w: int, h: int, fonts: list[int], fontInfo) -> int:
l, r, ans =0, len(fonts) -1, -1while l <= r:
m = (l + r) //2 fontSize = fonts[m]
if fontInfo.getHeight(fontSize) > h:
r = m -1continue width = sum(fontInfo.getWidth(fontSize, c) for c in text)
if width <= w:
ans = fontSize
l = m +1else:
r = m -1return ans
classSolution {
public:int maxFont(string text, int w, int h, vector<int>& fonts, FontInfo &fontInfo) {
int l =0, r = fonts.size() -1, ans =-1;
while (l <= r) {
int m = (l + r) /2;
int fontSize = fonts[m];
if (fontInfo.getHeight(fontSize) > h) {
r = m -1;
continue;
}
int width =0;
for (char c : text) width += fontInfo.getWidth(fontSize, c);
if (width <= w) {
ans = fontSize;
l = m +1;
} else {
r = m -1;
}
}
return ans;
}
};
classSolution {
funmaxFont(text: String, w: Int, h: Int, fonts: IntArray, fontInfo: FontInfo): Int {
var l = 0var r = fonts.size - 1var ans = -1while (l <= r) {
val m = (l + r) / 2val fontSize = fonts[m]
if (fontInfo.getHeight(fontSize) > h) {
r = m - 1continue }
var width = 0for (c in text) width += fontInfo.getWidth(fontSize, c)
if (width <= w) {
ans = fontSize
l = m + 1 } else {
r = m - 1 }
}
return ans
}
}
impl Solution {
pubfnmax_font(text: String, w: i32, h: i32, fonts: Vec<i32>, font_info: &FontInfo) -> i32 {
let (mut l, mut r, mut ans) = (0, fonts.len() asi32-1, -1);
while l <= r {
let m = (l + r) /2;
let font_size = fonts[m asusize];
if font_info.get_height(font_size) > h {
r = m -1;
continue;
}
let width: i32= text.chars().map(|c| font_info.get_width(font_size, c)).sum();
if width <= w {
ans = font_size;
l = m +1;
} else {
r = m -1;
}
}
ans
}
}