LeetCode 7.Reverse Integer
int reverse(int x) {
if(x == 0) return 0;
bool belowZero = x < 0 ? true : false;
long long num = x;
string str = to_string(abs(num));
std::reverse(str.begin(), str.end());
str.erase(0,str.find_first_not_of("0"));
stringstream ss(str);
ss >> num;
if(belowZero) num = 0-num;
if(num < INT_MIN || num > INT_MAX) return 0;
return num;
}
使用字符串实现,注意越界的问题,正负数的问题。
int reverse(int x) {
int res = 0;
while(x != 0) {
if(res <= INT_MAX / 10 && res >= INT_MIN / 10)
res = res * 10 + x % 10;
else
return 0;
x /= 10;
}
return res;
}
另一种实现,直接使用int
LeetCode 165. Compare Version Numbers
def compareVersion(self, version1: 'str', version2: 'str') -> 'int':
v1 = [int(x) for x in version1.split('.')]
v2 = [int(x) for x in version2.split('.')]
base = 1
if len(v1) > len(v2):
v1, v2 = v2, v1
base = -1
for i in range(len(v1)):
if v1[i] < v2[i]:
return -1*base
elif v1[i] > v2[i]:
return 1*base
for i in range(len(v1), len(v2)):
if v2[i] != 0:
return -1*base
return 0
思路:利用转换成int 的方法,消除前导0的影响,进行交换使得长度短的版本号在前,之后再检查即可。
def compareVersion(self, version1: 'str', version2: 'str') -> 'int':
v1 = [int(v) for v in version1.split('.')]
v2 = [int(v) for v in version2.split('.')]
for i in range(max(len(v1), len(v2))):
sub_v1 = v1[i] if i < len(v1) else 0
sub_v2 = v2[i] if i < len(v2) else 0
if sub_v1 > sub_v2:
return 1
elif sub_v1 < sub_v2:
return -1
return 0
优化版本:不用交换,直接用 sub_v1 = v[i] if i < len(v1) else 0
LeetCode 66. Plus One
vector plusOne(vector& digits) {
bool carry = true;
for(int i = digits.size()-1; i >= 0; --i) {
if(digits[i] == 9 && carry)
digits[i] = 0;
else {
digits[i] += carry ? 1 : 0;
carry = false;
}
}
if(carry) digits.insert(digits.begin(), 1);
return digits;
}
思路:用带进位的方法,如果最后还有进位则在最开始的地方插入1。
LeetCode 8. String to Integer (atoi)
def myAtoi(self, s: 'str') -> 'int':
#除掉多余的空格
s = s.lstrip()
if len(s) == 0:
return 0
#考虑正负号
belowZero = True if s[0] == '-' else False
s = s[1:] if s[0] == '-' or s[0] == '+' else s
#获取合法的数字范围
index = 0
while index < len(s) and s[index].isdigit():
index += 1
#加起来
s = s[:index]
num = 0
for c in s:
num *= 10
num += int(c)
#若为负号则 0-num
num = 0-num if belowZero else num
#溢出判断
if num < -2147483648:
return -2147483648
if num > 2147483647:
return 2147483647
return num
Python写法,发现C++的 long long 都不够用我就不想写了emmm
def myAtoi(self, s):
if len(s) == 0 : return 0
ls = list(s.strip())
sign = -1 if ls[0] == '-' else 1
if ls[0] in ['-','+'] : del ls[0]
ret, i = 0, 0
while i < len(ls) and ls[i].isdigit() :
ret = ret*10 + ord(ls[i]) - ord('0')
i += 1
return max(-2**31, min(sign * ret,2**31-1))
简洁版本Python
int myAtoi(string str) {
str.erase(0, str.find_first_not_of(' '));
if(str.size() == 0) return 0;
bool belowZero = false;
if(str[0] == '-') {
belowZero = true;
str.erase(0, 1);
}
int index = 0;
while(index < str.size() && str[index] >= '0' && str[index] <= '9')
index++;
str = str.substr(0, index);
long long num = 0;
for(int i = 0; i < str.size(); i++) {
num *= 10;
num += str[i]-'0';
}
if(belowZero) num = 0-num;
if(num < INT_MIN) return INT_MIN;
if(num > INT_MAX) return INT_MAX;
return num;
}
C++ long long 实现,会出现 Runtime Error
LeetCode 258.Add Digits
int addDigits(int num) {
int res = num;
while(res >= 10) {
num = 0;
while(res > 0) {
num += res % 10;
res /= 10;
}
res = num;
}
return res;
}
多次循环,迭代计算
int addDigits(int num) {
return (num - 1) % 9 + 1;
}
数学降维打击:数字根公式 LeetCode:Add Digits - 非负整数各位相加
LeetCode 67. Add Binary
string addBinary(string a, string b) {
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
if(a.size() > b.size())
swap(a, b);
int carry = 0;
string res = "";
for(int i = 0; i < a.size(); i++) {
int value = a[i]-'0' + b[i]-'0' + carry;
switch(value) {
case 0: res = '0' + res; carry = 0; break;
case 1: res = '1' + res; carry = 0; break;
case 2: res = '0' + res; carry = 1; break;
case 3: res = '1' + res; carry = 1; break;
}
}
for(int i = a.size(); i < b.size(); i++) {
int value = b[i]-'0' + carry;
switch(value) {
case 0: res = '0' + res; carry = 0; break;
case 1: res = '1' + res; carry = 0; break;
case 2: res = '0' + res; carry = 1; break;
}
}
if(carry)
res = '1' + res;
return res;
}
思路:逆序后逐位相加,最后注意进位。
string addBinary(string a, string b) {
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
int carry = 0, len = max(a.size(), b.size());
string res = "";
for(int i = 0; i < len; i++) {
int v1 = i < a.size() ? a[i]-'0' : 0;
int v2 = i < b.size() ? b[i]-'0' : 0;
int sum = v1 + v2 + carry;
carry = sum >= 2 ? 1 : 0;
sum = sum >= 2 ? sum-2 : sum;
res = char(sum + '0') + res;
}
if(carry)
res = '1' + res;
return res;
}
优化版本:效率相同,但是简洁许多。
LeetCode 43.Multiply Strings
string multiply(string num1, string num2) {
if(num1 == "0" || num2 == "0")
return "0";
if(num1.empty() || num2.empty())
return "0";
int len1 = num1.size(), len2 = num2.size();
string res(len1 + len2, '0');
for(int i = len1 - 1; i >= 0; i--)
for(int j = len2 - 1; j >= 0; j--) {
int n1 = num1[i]-'0', n2 = num2[j]-'0';
int mult = n1 * n2 + res[i+j+1] - '0';
res[i+j] = mult / 10 + res[i+j];
res[i+j+1] = mult % 10 + '0';
}
res.erase(0, res.find_first_not_of('0'));
return res;
}
思路:特殊的乘法,题解:43. Multiply Strings
LeetCode 29. Divide Two Integers
int divide(int dividend, int divisor) {
if (dividend == INT_MIN && divisor == -1) return INT_MAX;
long dvd = labs(dividend), dvs = labs(divisor), ans = 0;
int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;
while(dvd >= dvs) {
long tmp = dvs, m = 1;
while(dvd >= (tmp << 1)) {
tmp <<= 1;
m <<= 1;
}
dvd -= tmp;
ans += m;
}
return sign * ans;
}
LeetCode 69.sqrt(x)
int mySqrt(int x) {
if(x == 0 || x == 1) return x;
int high = x/2, low = 1, mid;
while(low < high) {
mid = low + (high - low)/2;
if(x / mid < mid)
high = mid - 1;
else if(mid+1 > x / (mid+1))
return mid;
else
low = mid + 1;
}
return high;
}
简单二分查找
int mySqrt(int x) {
if(x == 0 || x == 1) return x;
long r = x;
while (r*r > x)
r = (r + x/r) / 2;
return r;
}
牛顿迭代法:3-4 short lines, Integer Newton, Every Language
以上截图来自维基百科
LeetCode 50. Pow(x, n)
double myPow(double x, int n) {
if(n == 0 || x == 1) return 1;
if(n == 1) return x;
bool belowZero = n < 0 ? true : false;
long nn = labs(long(n));
double res, tmp = myPow(x, nn/2);
if(nn & 1)
res = tmp * tmp * x;
else
res = tmp * tmp;
if(belowZero)
res = 1/res;
return res;
}
思路:递归迭代,注意溢出即可。
LeetCode 367. Valid Perfect Square
bool isPerfectSquare(int num) {
long r = num;
while(r * r > num)
r = (r + num/r) / 2;
return r * r == num;
}
思路:用牛顿迭代法求整数平方根,后检查是不是完全平方根。
bool isPerfectSquare(int num) {
int tmp = sqrt(num);
if(tmp * tmp == num)
return true;
return false;
}
调用库函数 sqrt()
LeetCode 365. Water and Jug Problem
static int gcd(int a, int b) {
while(b){
int tmp = b;
b = a % b;
a = tmp;
}
return a;
}
bool canMeasureWater(int x, int y, int z) {
if(x + y < z) return false;
if(x == z || y == z || x + y == z) return true;
return z % gcd(x, y) == 0;
}
纯粹数学题目:若z是x,y的最大公因数的倍数则有解,或满足其他条件(x == z || y == z || x+y == z)。