C++小白修仙记_LeetCode刷题_算数运算
算术运算(难度:easy)
- 算术运算(难度:easy)
- 2469.温度转换
- 解法:
- 2235. 两整数相加
- 解法:
- 2413. 最小偶倍数
- 解法:
- 2160. 拆分数位后四位数字的最小和
- 解法:
- 官方 女少 解
- 2520. 统计能整除数字的位数
- 解法:
- 1688. 比赛中的配对次数
- 解法:
- 1281. 整数的各位积和之差
- 解法:
- 2427. 公因子的数目
- 解法1:暴力破解
- 解法2:(计算 gcd(a,b) 的因子)
- 728. 自除数
- 解法:
- 2119. 反转两次的数字
- 解法一:正常反转两次必定回到原值,排除特殊情况:值为0时为true、位数大于1并且有0结尾必定为false两种情况 其他都为正常情况
- 解法二:根据题意关系直接得结果
- 509. 斐波那契数
- 解法:利用递归思想 斐波那契数列:首项为0,前两项为1,后一项为前两项之和
- 9. 回文数
- 解法一:字符比对
- 解法二:数字法(官方解法)
- 70. 爬楼梯
- 解法:斐波那契数列
2469.温度转换
给你一个四舍五入到两位小数的非负浮点数 celsius 来表示温度,以 摄氏度(Celsius)为单位。
你需要将摄氏度转换为 开氏度(Kelvin)和 华氏度(Fahrenheit),并以数组 ans = [kelvin, fahrenheit] 的形式返回结果。
返回数组 ans 。与实际答案误差不超过 10-5 的会视为正确答案。
注意:
- 开氏度 = 摄氏度 + 273.15
- 华氏度 = 摄氏度 * 1.80 + 32.00
示例 1 :
输入: celsius = 36.50
输出: [309.65000,97.70000]
解释: 36.50 摄氏度:转换为开氏度是 309.65 ,转换为华氏度是 97.70 。
解法:
class Solution {
public:
vector<double> convertTemperature(double celsius) {
double Kelvin = 0.0;
double Fahrenheit = 0.0;
Kelvin = celsius + 273.15;
Fahrenheit = celsius * 1.80 + 32.00;
return {Kelvin,Fahrenheit};
}
};
2235. 两整数相加
给你两个整数 num1 和 num2,返回这两个整数的和。
示例 1:
输入:num1 = 12, num2 = 5
输出:17
解释:num1 是 12,num2 是 5 ,它们的和是 12 + 5 = 17 ,因此返回 17 。
示例 2:
输入:num1 = -10, num2 = 4
输出:-6
解释:num1 + num2 = -6 ,因此返回 -6 。
提示:
- -100 <= num1, num2 <= 100
解法:
class Solution {
public:
int sum(int num1, int num2) {
return num1+num2;
}
};
2413. 最小偶倍数
给你一个正整数 n ,返回 2 和 n 的最小公倍数(正整数)。
示例 1:
输入:n = 5
输出:10
解释:5 和 2 的最小公倍数是 10 。
示例 2:
输入:n = 6
输出:6
解释:6 和 2 的最小公倍数是 6 。注意数字会是它自身的倍数。
提示:
- 1 <= n <= 150
解法:
class Solution {
public:
int smallestEvenMultiple(int n) {
if(n % 2 == 0)
{
return n;
}else
{
return 2*n;
}
}
};
//或
class Solution {
public:
int smallestEvenMultiple(int n) {
return (n%2+1)*n;
}
};
2160. 拆分数位后四位数字的最小和
给你一个四位 正 整数 num 。请你使用 num 中的 数位 ,将 num 拆成两个新的整数 new1 和 new2 。new1 和 new2 中可以有 前导 0 ,且 num 中 所有 数位都必须使用。
比方说,给你 num = 2932 ,你拥有的数位包括:两个 2 ,一个 9 和一个 3 。一些可能的 [new1, new2] 数对为 [22, 93],[23, 92],[223, 9] 和 [2, 329] 。
请你返回可以得到的 new1 和 new2 的 最小 和。
示例:
输入:num = 2932
输出:52
解释:可行的 [new1, new2] 数对为 [29, 23] ,[223, 9] 等等。
最小和为数对 [29, 23] 的和:29 + 23 = 52 。
解法:
class Solution {
public:
int minimumSum(int num) {
int gewei = num % 10;
int shiwei = num % 100 / 10;
int baiwei = num % 1000 /100;
int qianwei = num / 1000;
int pair1;
int pair2;
vector<int>v;
v.push_back(gewei);
v.push_back(shiwei);
v.push_back(baiwei);
v.push_back(qianwei);
sort(v.begin(),v.end());
int count = v.size();
pair1 = v[0] * 10 + v[count - 1];
pair2 = v[1] * 10 + v[count - 2];
return pair2 + pair1;
}
};
官方 女少 解
class Solution {
public:
int minimumSum(int num) {
vector<int> v;
while(num)
{
v.push_back(num % 10);
num /= 10;
}
sort(v.begin(),v.end());
return (10 * v[0] + v[3]) + (10 * v[1] + v[2]);
}
};
2520. 统计能整除数字的位数
给你一个整数 num ,返回 num 中能整除 num 的数位的数目。
如果满足 nums % val == 0 ,则认为整数 val 可以整除 nums 。
示例:
输入:num = 7
输出:1
解释:7 被自己整除,因此答案是 1 。
解法:
class Solution {
public:
int countDigits(int num) {
int count = 0;
int m_Num = num;
while(m_Num)
{
if(num % (m_Num % 10) == 0)
{
count++;
}
m_Num /= 10;
}
return count;
}
};
1688. 比赛中的配对次数
给你一个整数 n ,表示比赛中的队伍数。比赛遵循一种独特的赛制:
如果当前队伍数是 偶数 ,那么每支队伍都会与另一支队伍配对。总共进行 n / 2 场比赛,且产生 n / 2 支队伍进入下一轮。
如果当前队伍数为 奇数 ,那么将会随机轮空并晋级一支队伍,其余的队伍配对。总共进行 (n - 1) / 2 场比赛,且产生 (n - 1) / 2 + 1 支队伍进入下一轮。
返回在比赛中进行的配对次数,直到决出获胜队伍为止。
示例:
输入:n = 7
输出:6
解释:比赛详情:
- 第 1 轮:队伍数 = 7 ,配对次数 = 3 ,4 支队伍晋级。
- 第 2 轮:队伍数 = 4 ,配对次数 = 2 ,2 支队伍晋级。
- 第 3 轮:队伍数 = 2 ,配对次数 = 1 ,决出 1 支获胜队伍。
总配对次数 = 3 + 2 + 1 = 6
解法:
class Solution {
public:
int numberOfMatches(int n) {
int xiachang_Num = 0;
while(n != 1)
{
if(n % 2 == 0)//偶数
{
n /= 2;
xiachang_Num += n;
}
else if(n % 2 == 1)//奇数
{
n = (n - 1 ) / 2 + 1;
xiachang_Num += n -1;
}
}
return xiachang_Num;
}
};
1281. 整数的各位积和之差
给你一个整数 n,请你帮忙计算并返回该整数「各位数字之积」与「各位数字之和」的差。
示例:
输入:n = 234
输出:15
解释:
各位数之积 = 2 * 3 * 4 = 24
各位数之和 = 2 + 3 + 4 = 9
结果 = 24 - 9 = 15
解法:
class Solution {
public:
int subtractProductAndSum(int n) {
int accumulate = 1;
int sum = 0;
int n_s = n;
while(n > 0)
{
n_s = n % 10;
accumulate *= n_s;
sum += n_s;
n /= 10;
}
return accumulate - sum;
}
};
2427. 公因子的数目
给你两个正整数 a 和 b ,返回 a 和 b 的 公 因子的数目。
如果 x 可以同时整除 a 和 b ,则认为 x 是 a 和 b 的一个 公因子 。
示例:
输入:a = 12, b = 6
输出:4
解释:12 和 6 的公因子是 1、2、3、6 。
解法1:暴力破解
class Solution {
public:
int commonFactors(int a, int b) {
int count = 0;
if(a > b)
{
for(int i = 1; i <= a - b; i++)
{
if(a % i == 0 && b % i == 0)
{
count++;
}
}
}
else if (a < b)
{
for(int i = 1; i <= b - a; i++)
{
if(a % i == 0 && b % i == 0)
{
count++;
}
}
}
else {
for(int i = 1; i <= a; i++)
{
if(a % i == 0 && b % i == 0)
{
count++;
}
}
}
return count;
}
};
解法2:(计算 gcd(a,b) 的因子)
我们可以先算出 a 和 b 的最大公约数 g,然后枚举 [1,..g] 中的每个数,判断其是否是 g 的因子,如果是,则答案加一。
class Solution {
public:
int commonFactors(int a, int b) {
int res = 0,g = gcd(a,b);
for(int i = 1; i <= g; ++i)
{
res += g % i == 0;
}
return res;
}
};
728. 自除数
自除数 是指可以被它包含的每一位数整除的数。
例如,128 是一个 自除数 ,因为 128 % 1 == 0,128 % 2 == 0,128 % 8 == 0。
自除数 不允许包含 0 。
给定两个整数 left 和 right ,返回一个列表,列表的元素是范围 [left, right](包括两个端点)内所有的 自除数 。
示例:
输入:left = 1, right = 22
输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22]
解法:
class Solution {
public:
bool isCompare(int num) //一元谓词 判断条件
{
int temp = num;
while(temp > 0)
{
int digit = temp % 10;
if(digit == 0 || num % digit != 0)
{
return false;
}
temp /= 10;
}
return true;
}
vector<int> selfDividingNumbers(int left, int right) {
vector<int>v;
for(int i = left; i <= right; i++)
{
if(isCompare(i))
//v.push_back(i);
v.emplace_back(i);//push_back() emplace_back()都可用,推荐用emplace_back()
//emplace_back();函数解释:
/* v.emplace_back(i); 是 C++ 中一种高效地向容器(如
std::vector)末尾添加元素的方式。与 push_back() 不同,
emplace_back() 直接在容器末尾的内存空间中就地构造元素,它
接收的参数 i 会被直接传递给元素类型的构造函数,避免了先创建
临时对象再拷贝或移动到容器中的开销。这不仅提升了性能(尤其
对于复杂或大型对象),也使代码更简洁,因为它直接在所需位置
构建元素,是现代 C++ 推荐的元素插入方法。 */
}
return v;
}
};
2119. 反转两次的数字
反转 一个整数意味着倒置它的所有位。
例如,反转 2021 得到 1202 。反转 12300 得到 321 ,不保留前导零 。
给你一个整数 num ,反转 num 得到 reversed1 ,接着反转 reversed1 得到 reversed2 。如果 reversed2 等于 num ,返回 true ;否则,返回 false 。
示例:
输入:num = 526
输出:true
解释:反转 num 得到 625 ,接着反转 625 得到 526 ,等于 num 。
解法一:正常反转两次必定回到原值,排除特殊情况:值为0时为true、位数大于1并且有0结尾必定为false两种情况 其他都为正常情况
class Solution {
public:
bool isSameAfterReversals(int num) {
int temp = num;
int count = 0;
if(temp % 10 == 0 && num == 0)
{
return true;
}
else
{
while(temp > 0)
{
int digit = temp % 10;
count++;
temp /= 10;
}
if(count > 1 && num % 10 == 0)
{
return false;
}
else
{
return true;
}
}
}
};
解法二:根据题意关系直接得结果
class Solution {
public:
bool isSameAfterReversals(int num) {
return num == 0 || num % 10 != 0;
}
};
509. 斐波那契数
斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n ,请计算 F(n) 。
示例:
输入:n = 2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1
解法:利用递归思想 斐波那契数列:首项为0,前两项为1,后一项为前两项之和
class Solution {
public:
int fib(int n) {
if(n == 0)
return 0;
if(n == 1 || n == 2)
return 1;
if( n > 2)
return fib(n-1) + fib(n-2);
return 0;
}
};
9. 回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
例如,121 是回文,而 123 不是。
示例 1:
输入:x = 121
输出:true
示例 2:
输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。
解法一:字符比对
class Solution {
public:
string ItStr(int x)
{
if(x == 0)
return "0";
string str = "";
while(x > 0)
{
int digit = x % 10;
str += char(digit - '0');
x /= 10;
}
return str;
}
bool isPalindrome(int x) {
if(x < 0 || (x % 10 == 0 && x != 0))
return false;
if (x < 10) // 0-9都是回文
return true;
string str = ItStr(x);//把x转换为字符串
for (int i = 0, j = str.size() - 1; i < j; i++, j--)
{
if(str[i] != str[j])
return false;
}
return true;
}
};
解法二:数字法(官方解法)
class Solution {
public:
bool isPalindrome(int x) {
if(x < 0 || (x % 10 == 0 && x != 0))
return false;
int revertedNumber = 0;
while(x > revertedNumber)
{
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10;
}
// 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
// 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
return x == revertedNumber || x == revertedNumber / 10;
}
};
70. 爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
- 1 阶 + 1 阶
- 2 阶
解法:斐波那契数列
class Solution {
public:
int climbStairs(int n) {
int p = 1;//一层楼时
int q = 2;//两层楼时
if(n == 1)
return p;
if(n == 2)
return q;
// 从第三楼开始,只有两种上楼方式,从前一层再爬一楼和从前二层再爬两楼。
// 可以推出 f(n) = f(n -1) + f(n -2)
// 直接递归会超时,所以用的for循环求结果
int r = 0;
for(int i = 3; i <= n; i++)
{
r = p + q;
p = q;
q = r;
}
return r;
}
};