13 Roman to Integer
通过逐个字符检查罗马数字字符串,并利用 isMinus 函数判断当前字符和下一个字符是否形成一个减法组合(如 IV, IX, XL 等)。如果是减法组合,则将组合的对应值加到结果中,并跳过两个字符;如果不是,则将单个字符的值加到结果中。整个过程使用一个 map 来存储罗马数字和它们的整数值,遍历字符串以计算总和。
class Solution {
public:
bool isMinus(char front, char back) {
// 判断前一个字符是否应做减法
if (front == 'C') {
return back == 'M' || back == 'D';
} else if (front == 'X') {
return back == 'C' || back == 'L';
} else if (front == 'I') {
return back == 'X' || back == 'V';
}
return false;
}
int romanToInt(string s) {
// 使用map来存储罗马数字及其对应的整数值
map<string, int> roman = {{"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400},
{"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40},
{"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}};
int res = 0, i = 0, j = 1;
while (i < s.size()) {
if (j < s.size() && isMinus(s[i], s[j])) {
// 处理组合字符的情况
string p = "";
p += s[i];
p += s[j];
res += roman[p];
i += 2;
} else {
// 处理单个字符的情况
string p = "";
p += s[i];
res += roman[p];
i++;
}
j = i + 1;
}
return res;
}
};
官方题解优化部分:isMenus的判断:建立单字符的哈希表,判断前者对应数值是否小于后者,如果小于,则减去当前value;反之, 则加上value。【默写】
class Solution {
private:
unordered_map<char , int> roman = {
{'I', 1},
{'V', 5},
{'X', 10},
{'L', 50},
{'C', 100},
{'D', 500},
{'M', 1000},
};
public:
int romanToInt(string s) {
int ans = 0;
int n = s.length();
for (int i = 0; i < n; ++i) {
int value = roman[s[i]];
if(i < n-1 && value < roman[s[i+1]]){
ans -= value;
}else{
ans += value;
}
}
return ans;
}
};
6 Zigzag Conversion
这类题类似于公式推导,理清思路即可。将字符串按照指定的行数以“Z”字形排列,然后逐行读取字符。通过计算每个字符在原始字符串中的位置,分为竖直行和斜行两种情况处理。逐行遍历每组字符,依次将竖直行和斜行的字符添加到结果字符串中,最终形成按行读取后的字符串。
class Solution {
public:
string convert(string s, int numRows) {
//z字形 公式计算 和numPows有关
//竖行 斜行
if(numRows == 1)return s;
int x = s.size()/numRows;
int n = numRows*2 - 2 ; // 每组个数 一竖一斜为一组
int group = s.size()%numRows? x+1 : x;//组的个数
string ans = "";
for(int i = 0; i < numRows ; i++){//变形后的行数
for(int g = 0 ; g < group; g++){//组数
int mid = n*g + (numRows-1);
int line = g*n+i;
int lean = mid*2 - line;
if(line < s.size()){
//竖行
ans.push_back(s[line]);
}
if(lean < s.size() && i != 0 && i != numRows-1 ){//判断是否为第一行或最后一行
//斜行
ans.push_back(s[lean]);
}
}
}
return ans;
}
};
类似于官方题解中的方法三,下图很清晰的解释了这种思路:
该段评论来自于题解讨论区,原文发布于评论链接