7. 整数反转
给你一个 32 位的有符号整数x
,返回将 x
中的数字部分反转后的结果。
-如果反转后整数超过 32 位的有符号整数的范围 [2^31, 2^31 -1]
,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
提示:
-2^31 <= x <= 2^31 - 1
解法1:
#include <bits/stdc++.h> using namespace std; class Solution { public: int reverse(int x) { int MAX = 0x7fffffff; int MIN = 1 << 31; ostringstream stream, smax, smin; string ss; stream << x; ss += stream.str(); smax << MAX; string max_num = smax.str(); smin << MIN; string min_num = smin.str(); std::reverse(ss.begin(), ss.end()); if (x < 0) { ss.insert(0, "-"); ss.pop_back(); } if (x > 0 && ss.size() >= max_num.size() && (ss > max_num)) return 0; else if (x < 0 && ss.size() >= min_num.size() && ss > min_num) return 0; else return atoi(ss.c_str()); } }; int main() { Solution s; vector<int> nums = {123,-123,120,0}; for(auto num:nums) cout << s.reverse(num) << endl; return 0; }
解法2:
#include <bits/stdc++.h> using namespace std; class Solution { public: #define INT_MAX 2147483647 #define INT_MIN (-INT_MAX - 1) int reverse(int x) { int flag = x < 0 ? -1 : 1; int num = 0; while (x) { if ((flag == -1 && (INT_MIN / 10 > num)) || (flag == 1 && INT_MAX / 10 < num)) return 0; num = num * 10 + x % 10; x /= 10; } return num; } }; int main() { Solution s; vector<int> nums = {123,-123,120,0}; for(auto num:nums) cout << s.reverse(num) << endl; return 0; }
解法3:
#include <bits/stdc++.h> using namespace std; class Solution { public: int reverse(int x) { int rev = 0; while (x != 0) { int pop = x % 10; x = x / 10; if (rev > INT_MAX / 10 || (rev == INT_MAX / 10 && pop > 7)) return 0; if (rev < INT_MIN / 10 || (rev == INT_MIN / 10 && pop < -8)) return 0; rev = rev * 10 + pop; } return rev; } }; int main() { Solution s; vector<int> nums = {123,-123,120,0}; for(auto num:nums) cout << s.reverse(num) << endl; return 0; }
9. 回文数
给你一个整数 x
,如果 x
是一个回文整数,返回 true
;否则,返回 false
。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121
是回文,而 123
不是。
示例 1:
输入:x = 121
输出:true
示例 2:
输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。
示例 4:
输入:x = -101
输出:false
提示:
-2^31 <= x <= 2^31 - 1
进阶:你能不将整数转为字符串来解决这个问题吗?
解法1:
#include <bits/stdc++.h> using namespace std; class Solution { public: bool isPalindrome(long int x) { long int rev; if (x < 0) return false; string str_x = to_string(x); std::reverse(str_x.begin(), str_x.end()); stringstream out(str_x); out >> rev; return x == rev; } }; int main() { Solution s; vector<int> nums = {121,-121,10,-101}; for(auto num:nums) cout << s.isPalindrome(num) << endl; return 0; }
解法2:
#include <bits/stdc++.h> using namespace std; class Solution { public: bool isPalindrome(long int x) { long int midrev = 0; if (x < 0 || (x % 10 == 0 && x != 0)) return false; while (x > midrev) { midrev = midrev * 10 + x % 10; x /= 10; } return midrev == x || midrev / 10 == x; } }; int main() { Solution s; vector<int> nums = {121,-121,10,-101}; for(auto num:nums) cout << s.isPalindrome(num) << endl; return 0; }
解法3:
#include <bits/stdc++.h> using namespace std; class Solution { public: bool isPalindrome(long int x) { if (x < 0) return false; long int sum = 0, t = x; while(x) { sum = sum * 10 + x % 10; x /= 10; } return t == sum; } }; int main() { Solution s; vector<int> nums = {121,-121,10,-101}; for(auto num:nums) cout << s.isPalindrome(num) << endl; return 0; }
12. 整数转罗马数字
罗马数字包含以下七种字符: 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
解法1:
#include <bits/stdc++.h> using namespace std; class Solution { public: string getNum1000(int num1000) { if (num1000 == 3) { return "MMM"; } else if (num1000 == 2) { return "MM"; } else if (num1000 == 1) { return "M"; } else { return ""; } } string getNum100(int num100) { switch (num100) { case 1: return "C"; case 2: return "CC"; case 3: return "CCC"; case 4: return "CD"; case 5: return "D"; case 6: return "DC"; case 7: return "DCC"; case 8: return "DCCC"; case 9: return "CM"; default: return ""; } } string getNum10(int num10) { switch (num10) { case 1: return "X"; case 2: return "XX"; case 3: return "XXX"; case 4: return "XL"; case 5: return "L"; case 6: return "LX"; case 7: return "LXX"; case 8: return "LXXX"; case 9: return "XC"; default: return ""; } } string getNum1(int num1) { switch (num1) { case 1: return "I"; case 2: return "II"; case 3: return "III"; case 4: return "IV"; case 5: return "V"; case 6: return "VI"; case 7: return "VII"; case 8: return "VIII"; case 9: return "IX"; default: return ""; } } string intToRoman(int num) { int num1000 = num / 1000; int num100 = (num % 1000) / 100; int num10 = (num % 100) / 10; int num1 = (num % 10); string res; res = getNum1000(num1000) + getNum100(num100) + getNum10(num10) + getNum1(num1); return res; } }; int main() { Solution s; vector<int> nums = {3,4,9,58,1994}; for(auto num:nums) cout << s.intToRoman(num) << endl; return 0; }
解法2:
#include <bits/stdc++.h> using namespace std; class Solution { public: string intToRoman(int num) { int values[13] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; string reps[13] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; string res; for (int i = 0; i < 13; i++) { while (num >= values[i]) { num -= values[i]; res += reps[i]; } } return res; } }; int main() { Solution s; vector<int> nums = {3,4,9,58,1994}; for(auto num:nums) cout << s.intToRoman(num) << endl; return 0; }
解法3:
#include <bits/stdc++.h> using namespace std; class Solution { public: string intToRoman(int num) { string bit1[10] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}; string bit10[10] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}; string bit100[10] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}; string bit1000[4] = {"", "M", "MM", "MMM"}; return bit1000[num / 1000] + bit100[num % 1000 / 100] + bit10[num % 100 / 10] + bit1[num % 10]; } }; int main() { Solution s; vector<int> nums = {3,4,9,58,1994}; for(auto num:nums) cout << s.intToRoman(num) << endl; return 0; }
13. 罗马数字转整数
罗马数字包含以下七种字符: 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
解法1:
#include <bits/stdc++.h> using namespace std; class Solution { public: int romanToInt(string s) { int sum = 0; for (int i = 1; i <= s.size(); i++) { if (s[i - 1] == 'I' && s[i] == 'V') { sum += 4; i++; } else if (s[i - 1] == 'I' && s[i] == 'X') { sum += 9; i++; } else if (s[i - 1] == 'X' && s[i] == 'L') { sum += 40; i++; } else if (s[i - 1] == 'X' && s[i] == 'C') { sum += 90; i++; } else if (s[i - 1] == 'C' && s[i] == 'D') { sum += 400; i++; } else if (s[i - 1] == 'C' && s[i] == 'M') { sum += 900; i++; } else if (s[i - 1] == 'I') { sum += 1; } else if (s[i - 1] == 'V') { sum += 5; } else if (s[i - 1] == 'X') { sum += 10; } else if (s[i - 1] == 'L') { sum += 50; } else if (s[i - 1] == 'C') { sum += 100; } else if (s[i - 1] == 'D') { sum += 500; } else if (s[i - 1] == 'M') { sum += 1000; } } return sum; } }; int main() { Solution s; vector<string> roma = {"III","IV","IX","LVIII","MCMXCIV"}; for (auto r:roma) cout << s.romanToInt(r) << endl; return 0; }
解法2:
#include <bits/stdc++.h> using namespace std; class Solution { public: int romanToInt(string s) { int result = 0; int n = s.length(); for (int i = 0; i < n; i++) { switch (s[i]) { case 'I': if (i < n - 1 && s[i + 1] == 'V') { result += 4; i++; } else if (i < n - 1 && s[i + 1] == 'X') { result += 9; i++; } else result++; break; case 'V': result += 5; break; case 'X': if (i < n - 1 && s[i + 1] == 'L') { result += 40; i++; } else if (i < n - 1 && s[i + 1] == 'C') { result += 90; i++; } else result += 10; break; case 'L': result += 50; break; case 'C': if (i < n - 1 && s[i + 1] == 'D') { result += 400; i++; } else if (i < n - 1 && s[i + 1] == 'M') { result += 900; i++; } else result += 100; break; case 'D': result += 500; break; case 'M': result += 1000; } } return result; } }; int main() { Solution s; vector<string> roma = {"III","IV","IX","LVIII","MCMXCIV"}; for (auto r:roma) cout << s.romanToInt(r) << endl; return 0; }
解法3:
#include <bits/stdc++.h> using namespace std; class Solution { public: int romanToInt(string s) { int result = 0; map<char, int> luomab; luomab.insert(map<char, int>::value_type('I', 1)); luomab.insert(map<char, int>::value_type('V', 5)); luomab.insert(map<char, int>::value_type('X', 10)); luomab.insert(map<char, int>::value_type('L', 50)); luomab.insert(map<char, int>::value_type('C', 100)); luomab.insert(map<char, int>::value_type('D', 500)); luomab.insert(map<char, int>::value_type('M', 1000)); for (int i = 0; i < s.length(); i++) { if (luomab[s[i]] >= luomab[s[i + 1]]) result += luomab[s[i]]; else { result += (luomab[s[i + 1]] - luomab[s[i]]); i++; } } return result; } }; int main() { Solution s; vector<string> roma = {"III","IV","IX","LVIII","MCMXCIV"}; for (auto r:roma) cout << s.romanToInt(r) << endl; return 0; }
29. 两数相除
给定两个整数,被除数 dividend
和除数 divisor
。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend
除以除数 divisor
得到的商。
整数除法的结果应当截去(truncate
)其小数部分,例如:truncate(8.345) = 8
以及 truncate(-2.7335) = -2
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
示例 2:
输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333..) = -2
提示:
- 被除数和除数均为 32 位有符号整数。
- 除数不为 0。
- 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1]。本题中,如果除法结果溢出,则返回 2^31 − 1。
解法1:
#include <bits/stdc++.h> using namespace std; class Solution { public: int divide(int dividend, int divisor) { int INI_MIN = -2147483648, INI_MAX = 2147483647; if (dividend == divisor) return 1; if (divisor == 1) return dividend; if (dividend == INI_MIN && divisor == -1) return INI_MAX; if (divisor == INI_MIN) { if (dividend == INI_MIN) return 1; else return 0; } bool sign = false; if (dividend > 0 && divisor > 0 || dividend < 0 && divisor < 0) { sign = true; } int result_1 = 0; if (dividend == INI_MIN) { if (divisor > 0) dividend = dividend + divisor; else dividend = dividend - divisor; result_1++; } dividend = abs(dividend); divisor = abs(divisor); while (dividend >= divisor) { unsigned int temp = divisor, res = 1; while (dividend >= (temp << 1)) { res <<= 1; temp <<= 1; } result_1 += res; dividend -= temp; } if (sign == true) { return result_1; } else { return -result_1; } } }; int main() { Solution s; cout << s.divide(10, 3) << endl; cout << s.divide(7, -3) << endl; return 0; }
解法2:
#include <bits/stdc++.h> using namespace std; class Solution { public: int divide(int dividend, int divisor) { int signal = 1; unsigned int dvd = dividend; if (dividend < 0) { signal *= -1; dvd = ~dvd + 1; } unsigned int dvs = divisor; if (divisor < 0) { signal *= -1; dvs = ~dvs + 1; } int shift = 0; while (dvd > dvs << shift) { shift++; } unsigned int res = 0; while (dvd >= dvs) { while (dvd < dvs << shift) { shift--; } res |= (unsigned int)1 << shift; dvd -= dvs << shift; } if (signal == 1 && res >= INT_MAX) { return INT_MAX; } else { return res * signal; } } }; int main() { Solution s; cout << s.divide(10, 3) << endl; cout << s.divide(7, -3) << endl; return 0; }
解法3:
#include <bits/stdc++.h> using namespace std; class Solution { public: int divide(int dividend, int divisor) { if (dividend == INT_MIN && divisor == -1) return INT_MAX; if (dividend == 0) return 0; int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1; long x = (dividend < 0) ? -(long)dividend : (long)dividend; long y = (divisor < 0) ? -(long)divisor : (long)divisor; long result = 0; while (x >= y) { long temp = y, mid = 1; while (x >= (temp << 1)) { mid <<= 1; temp <<= 1; } result += mid; x -= temp; } return sign > 0 ? result : -result; } }; int main() { Solution s; cout << s.divide(10, 3) << endl; cout << s.divide(7, -3) << endl; return 0; }
完