当前版本号[20231114]。
版本 | 修改说明 |
---|---|
20231114 | 初版 |
给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 。
如果小数部分为循环小数,则将循环的部分括在括号内。
如果存在多个答案,只需返回 任意一个 。
对于所有给定的输入,保证 答案字符串的长度小于 104 。
示例 1:
输入:numerator = 1, denominator = 2
输出:“0.5”
示例 2:
输入:numerator = 2, denominator = 1
输出:“2”
示例 3:
输入:numerator = 2, denominator = 3
输出:“0.(6)”
示例 4:
输入:numerator = 4, denominator = 333
输出:“0.(012)”
示例 5:
输入:numerator = 1, denominator = 5
输出:“0.2”
提示:
-231 <= numerator, denominator <= 231 - 1
denominator != 0
首先检查分子是否为0,如果是,则直接返回"0"。
// 如果分子为0,直接返回"0"
if (numerator == 0)
return "0";
创建一个StringBuilder对象str,用于构建结果字符串。
检查分子和分母的符号是否不同,如果不同,则在结果字符串前加上负号。
// 如果分子和分母的符号不同,需要在结果字符串前加上负号
if (numerator < 0 ^ denominator < 0)
str.append('-');
计算分子和分母的绝对值,并将它们转换为长整型dividend和divisor。
// 计算分子和分母的绝对值,并将它们转换为长整型
long dividend = Math.abs(Long.valueOf(numerator));
long divisor = Math.abs(Long.valueOf(denominator));
将商添加到结果字符串中。
// 将商添加到结果字符串中
str.append(String.valueOf(dividend / divisor));
计算余数remainter。
// 计算余数
long remainter = dividend % divisor;
如果余数为0,说明已经完成了转换,直接返回结果字符串。
// 如果余数为0,说明已经完成了转换,直接返回结果字符串
if (remainter == 0)
return str.toString();
在结果字符串后加上一个小数点。
// 在结果字符串后加上一个小数点
str.append('.');
创建一个哈希表map,用于记录已经出现过的余数。
// 创建一个哈希表,用于记录已经出现过的余数
Map<Long, Integer> map = new HashMap<>();
当余数不为0时,继续进行转换: a. 如果哈希表中已经存在当前的余数,说明出现了循环节,需要插入括号。
// 当余数不为0时,继续进行转换
while (remainter != 0) {
// 如果哈希表中已经存在当前的余数,说明出现了循环节,需要插入括号
if (map.containsKey(remainter)) {
str.insert(map.get(remainter), "(");
str.append(")");
break;
}
b. 将当前的余数和它在结果字符串中的位置添加到哈希表中。
// 将当前的余数和它在结果字符串中的位置添加到哈希表中
map.put(remainter, str.length());
c. 将余数乘以10,得到下一位小数。
// 将余数乘以10,得到下一位小数
remainter *= 10;
d. 将下一位小数添加到结果字符串中。
// 将下一位小数添加到结果字符串中
str.append(String.valueOf(remainter / divisor));
e. 更新余数。
// 更新余数
remainter %= divisor;
返回最终的结果字符串。
// 返回最终的结果字符串
return str.toString();
这段代码是将一个分数转换为小数表示。
class Solution {
public String fractionToDecimal(int numerator, int denominator) {
if (numerator == 0)
return "0";
StringBuilder str = new StringBuilder();
if (numerator < 0 ^ denominator < 0)
str.append('-');
long dividend = Math.abs(Long.valueOf(numerator));
long divisor = Math.abs(Long.valueOf(denominator));
str.append(String.valueOf(dividend / divisor));
long remainter = dividend % divisor;
if (remainter == 0)
return str.toString();
str.append('.');
Map<Long, Integer> map = new HashMap<>();
while (remainter != 0) {
if (map.containsKey(remainter)) {
str.insert(map.get(remainter), "(");
str.append(")");
break;
}
map.put(remainter, str.length());
remainter *= 10;
str.append(String.valueOf(remainter / divisor));
remainter %= divisor;
}
return str.toString();
}
}
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给你一个整数,将其转为罗马数字。
示例 1:
输入: num = 3
输出: “III”
示例 2:
输入: num = 4
输出: “IV”
示例 3:
输入: num = 9
输出: “IX”
示例 4:
输入: num = 58
输出: “LVIII”
解释: L = 50, V = 5, III = 3.
示例 5:
输入: num = 1994
输出: “MCMXCIV”
解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
1 <= num <= 3999
给定一个整数n,将其转为罗马数字。解题思路如下:
例如,给定整数n=56,其罗马数字为XII。
初始化一个变量n为0,用于存储转换后的整数值。
使用for循环遍历输入的字符串s。
// 使用for循环遍历字符串s中的每个字符
for (int i = 0; i < s.length();)
在循环中,首先获取当前字符c。
// 获取当前字符c
char c = s.charAt(i);
根据字符c的值进行判断:
如果c是’I’,则表示这是一个"I"字符。需要判断下一个字符是否为’V’或’X’,如果是,则将对应的整数值加到n上,并将i增加2;否则,将1加到n上,并将i增加1。
// 判断当前字符是否为'I'
if (c == 'I') {
// 如果当前字符后面还有字符,继续判断下一个字符
if (i + 1 < s.length()) {
// 如果下一个字符是'V',将4加到n上,并将i增加2
if (s.charAt(i + 1) == 'V') {
n += 4;
i += 2;
} else if (s.charAt(i + 1) == 'X') { // 如果下一个字符是'X',将9加到n上,并将i增加2
n += 9;
i += 2;
} else { // 如果下一个字符不是'V'或'X',将1加到n上,并将i增加1
n += 1;
i++;
}
} else { // 如果当前字符后面没有字符,将1加到n上,并将i增加1
n += 1;
i++;
}
}
如果c是’X’,则表示这是一个"X"字符。需要判断下一个字符是否为’L’或’C’,如果是,则将对应的整数值加到n上,并将i增加2;否则,将10加到n上,并将i增加1。
else if (c == 'X') { // 如果当前字符是'X',进行类似的判断和操作
if (i + 1 < s.length()) {
if (s.charAt(i + 1) == 'L') {
n += 40;
i += 2;
} else if (s.charAt(i + 1) == 'C') {
n += 90;
i += 2;
} else {
n += 10;
i++;
}
} else {
n += 10;
i++;
}
}
如果c是’C’,则表示这是一个"C"字符。需要判断下一个字符是否为’D’或’M’,如果是,则将对应的整数值加到n上,并将i增加2;否则,将100加到n上,并将i增加1。
else if (c == 'C') { // 如果当前字符是'C',进行类似的判断和操作
if (i + 1 < s.length()) {
if (s.charAt(i + 1) == 'D') {
n += 400;
i += 2;
} else if (s.charAt(i + 1) == 'M') {
n += 900;
i += 2;
} else {
n += 100;
i++;
}
} else {
n += 100;
i++;
}
}
如果c是’V’、‘L’、‘D’或’M’,则分别将5、50、500和1000加到n上,并将i增加1。
else if (c == 'V') { // 如果当前字符是'V',将5加到n上,并将i增加1
n += 5;
i++;
} else if (c == 'L') { // 如果当前字符是'L',将50加到n上,并将i增加1
n += 50;
i++;
} else if (c == 'D') { // 如果当前字符是'D',将500加到n上,并将i增加1
n += 500;
i++;
} else if (c == 'M') { // 如果当前字符是'M',将1000加到n上,并将i增加1
n += 1000;
i++;
}
}
循环结束后,返回n作为结果。
这段代码是将罗马数字转换为整数的函数。
class Solution {
public int romanToInt(String s) {
int n = 0;
for (int i = 0; i < s.length();) {
char c = s.charAt(i);
if (c == 'I') {
if (i + 1 < s.length()) {
if (s.charAt(i + 1) == 'V') {
n += 4;
i += 2;
} else if (s.charAt(i + 1) == 'X') {
n += 9;
i += 2;
} else {
n += 1;
i++;
}
} else {
n += 1;
i++;
}
} else if (c == 'X') {
if (i + 1 < s.length()) {
if (s.charAt(i + 1) == 'L') {
n += 40;
i += 2;
} else if (s.charAt(i + 1) == 'C') {
n += 90;
i += 2;
} else {
n += 10;
i++;
}
} else {
n += 10;
i++;
}
} else if (c == 'C') {
if (i + 1 < s.length()) {
if (s.charAt(i + 1) == 'D') {
n += 400;
i += 2;
} else if (s.charAt(i + 1) == 'M') {
n += 900;
i += 2;
} else {
n += 100;
i++;
}
} else {
n += 100;
i++;
}
} else if (c == 'V') {
n += 5;
i++;
} else if (c == 'L') {
n += 50;
i++;
} else if (c == 'D') {
n += 500;
i++;
} else if (c == 'M') {
n += 1000;
i++;
}
}
return n;
}
}
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842…, 由于返回类型是整数,小数部分将被舍去。
初始化左边界left为0,右边界right为46340(因为题目要求返回的结果不超过32位有符号整数的范围)。
// 初始化左边界left为0,右边界right为46340
int left = 0, right = 46340;
进入循环,当left小于right时执行以下操作:
a. 计算中间值mid,即(left + right) / 2。
// 计算中间值mid
int mid = (left + right) / 2;
b. 如果mid的平方小于x,说明平方根在mid的右侧,将left更新为mid + 1。
// 如果mid的平方小于x,说明平方根在mid的右侧
if (mid * mid < x)
left = mid + 1;
c. 如果mid的平方大于x,说明平方根在mid的左侧,需要进一步判断:
i. 如果(mid - 1)的平方小于等于x,说明平方根就是mid - 1,直接返回mid - 1。
ii. 否则,将right更新为mid - 1。
d. 如果mid的平方等于x,说明找到了平方根,直接返回mid。
// 如果mid的平方大于x,说明平方根在mid的左侧
else if (mid * mid > x)
// 如果(mid - 1)的平方小于等于x,说明平方根就是mid - 1
if ((mid - 1) * (mid - 1) <= x)
return mid - 1;
// 否则,将右边界right更新为mid - 1
else
right = mid - 1;
// 如果mid的平方等于x,说明找到了平方根,直接返回mid
else
return mid;
}
当循环结束后,如果left的平方大于x,说明平方根在left的左侧,将left减1后返回。
如果left的平方小于等于x,说明平方根就是left,直接返回left。
// 如果循环结束后,左边界的平方大于x,说明平方根在左边界的左侧,将左边界减1后返回
if (left * left > x)
return left - 1;
// 否则,直接返回左边界
return left;
这段代码主要是使用二分查找算法来求解一个整数的平方根。
class Solution {
public int mySqrt(int x) {
int left = 0, right = 46340;
while (left < right) {
int mid = (left + right) / 2;
if (mid * mid < x)
left = mid + 1;
else if (mid * mid > x)
if ((mid - 1) * (mid - 1) <= x)
return mid - 1;
else
right = mid - 1;
else
return mid;
}
if (left * left > x)
return left - 1;
return left;
}
}