
给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。
示例:
输入: 38
输出: 2
解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。进阶: 你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?
题目地址 https://leetcode-cn.com/problems/add-digits/
代码模板
public class Solution {
public int AddDigits(int num) {
}
}测试数据
输入 1
输出 1
输入 10
输出 1
输入 38
输出 2
输入 199
输出 1
输入 8888
输出 5笔者的方法:
使用了while循环,除一次计算一次,原始数和各位数和同时变化。时间在70ms内。
public static int Csum(int num)
{
if (num < 10) //小于10的数直接返回
return num;
int shi = 0; //记录个位数相加
while (num > 0)
{
if (num >= 10)
{
shi += num % 10;
num = num / 10;
}
else if (num < 10)
{
shi += num;
num = num / 10;
}
if (shi >= 10) shi = shi % 10 + shi / 10; //超过10的个位数重新变化
}
return shi;
}方法二 弃九验算法
同样在 60-70ms
public class Solution {
public int AddDigits(int num) {
if(num==0)
return 0;
if(num%9==0)
return 9;
return num%9;
}
}给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321示例 2:
输入: -123
输出: -321示例 3:
输入: 120
输出: 21注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0
题目地址 https://leetcode-cn.com/problems/reverse-integer/
代码模板
public class Solution {
public int Reverse(int x) {
}
}笔者方法 68ms左右
public class Solution
{
public int Reverse(int x)
{
int num = 0;
while (x != 0)
{
int i = x % 10;
x = x / 10;
//C# int32 范围 [-2147483647~2147483647]
if (num > int.MaxValue / 10 )
return 0;
if (num < int.MinValue / 10)
return 0;
num = num * 10 + i;
}
return num;
}
}判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
题目地址:https://leetcode-cn.com/problems/palindrome-number
示例 1:
输入: 121
输出: true示例 2:
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。示例 3:
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。进阶:
你能不将整数转为字符串来解决这个问题吗?
代码模板
public class Solution {
public bool IsPalindrome(int x) {
}
}笔者的代码
运行时间在120ms左右,笔者的思路是:如果一个数字的反序还是等于这个数,那么这个数就是回文数。
以下代码无法解决反序后可能溢出,可以利用上一题的代码进行溢出检查。
当然,一个int类型的数,如果是回文,那么他的反序肯定不会溢出,反之其反序发生溢出则肯定不是回文数。
public class Solution
{
public bool IsPalindrome(int x)
{
if (x < 0) return false;
int xx = x;
int num = 0; //x的反序
while (xx != 0) //求反序
{
int i = xx % 10;
xx = xx / 10;
num = num * 10 + i;
}
if (x == num) //如果x的反序num==x,那么这个数字是回文数
return true;
else
return false;
}
}加try-catch,耗时增加 10~20ms
try {
while (xx != 0)
{
int i = xx % 10;
xx = xx / 10;
num = num * 10 + i;
}
}
catch
{
return false;
}
官方这道题给出了示例代码,耗时120ms左右,思路是只反序一半,反序后的原始数、反序一半的数进行比较,也就不用检查溢出。
public class Solution {
public bool IsPalindrome(int x) {
// 特殊情况:
// 如上所述,当 x < 0 时,x 不是回文数。
// 同样地,如果数字的最后一位是 0,为了使该数字为回文,
// 则其第一位数字也应该是 0
// 只有 0 满足这一属性
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;
}
}别人用字符串方式进行判断(虽然题目说不能用string),耗时150-180ms,不太稳定
public class Solution
{
public bool IsPalindrome(int x)
{
string str = x.ToString();
for (int i = 0; i < str.Length / 2; ++i)
{
if (str[i] != str[str.Length - 1 - i])
{
return false;
}
}
return true;
}
}罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
题目地址 https://leetcode-cn.com/problems/roman-to-integer/submissions/
字符 数值
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 到 3999 的范围内。
示例 1:
输入: "III"
输出: 3示例 2:
输入: "IV"
输出: 4示例 3:
输入: "IX"
输出: 9示例 4:
输入: "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.示例 5:
输入: "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.笔者的方法:
时间200ms左右,
思路是
public class Solution
{
public int RomanToInt(string s)
{
char[] c = s.ToCharArray(); //将其转为字符数组
int sum = 0; //值
Hashtable hashtable = new Hashtable();
//7个基本单位
hashtable.Add("I", 1);
hashtable.Add("V", 5);
hashtable.Add("X", 10);
hashtable.Add("L", 50);
hashtable.Add("C", 100);
hashtable.Add("D", 500);
hashtable.Add("M", 1000);
//加上6种情况
hashtable.Add("IV", 4);
hashtable.Add("IX", 9);
hashtable.Add("XL", 40);
hashtable.Add("XC", 90);
hashtable.Add("CD", 400);
hashtable.Add("CM", 900);
换成字典
public class Solution
{
public int RomanToInt(string s)
{
char[] c = s.ToCharArray(); //将其转为字符数组
int sum = 0; //值
Dictionary<string, int> dictionary = new Dictionary<string, int>();
//7个基本单位
dictionary.Add("I", 1);
dictionary.Add("V", 5);
dictionary.Add("X", 10);
dictionary.Add("L", 50);
dictionary.Add("C", 100);
dictionary.Add("D", 500);
dictionary.Add("M", 1000);
//加上6种情况
dictionary.Add("IV", 4);
dictionary.Add("IX", 9);
dictionary.Add("XL", 40);
dictionary.Add("XC", 90);
dictionary.Add("CD", 400);
dictionary.Add("CM", 900);
以上两个例子都会进行较多的装箱拆箱,下面主要使用if-else,switch,空间花销较大,但是如果测试例子较多,进行大量计算,时间会相对少一点。
public class Solution
{
public int RomanToInt(string s)
{
int sum = 0; //值
for (int i = 0; i < s.Length; i++)
{
if (i + 1 < s.Length) //如果后面还有别的字符
{
if (s[i] == 'I')
{
int a = 0;
switch (s[i + 1]) //"i%"
{
case 'V': a = 4; i++; break;
case 'X': a = 9; i++; break;
default: a = 1; break;
}
sum += a;
}
else if (s[i] == 'X')
{
int a = 0;
switch (s[i + 1]) //"X%"
{
case 'L': a = 40; i++; break;
case 'C': a = 90; i++; break;
default: a = 10; break;
}
sum += a;
}
else if (s[i] == 'C')
{
int a = 0;
switch (s[i + 1]) //"X%"
{
case 'D': a = 400; i++; break;
case 'M': a = 900; i++; break;
default: a = 100; break;
}
sum += a;
}
else
{
int a = 0;
switch (s[i])
{case 'V': a = 5; break;case 'L': a = 50; break;case 'D': a = 500; break;
case 'M': a = 1000; break;
}
sum += a;
}
}
else
{
int a = 0;
switch (s[i])
{
case 'I': a = 1; break;
case 'V': a = 5; break;
case 'X': a = 10; break;
case 'L': a = 50; break;
case 'C': a = 100; break;
case 'D': a = 500; break;
case 'M': a = 1000; break;
}
sum += a;
}
}
return sum;
}
}