各位相加
给定一个非负整数 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左右,
思路是
- 把所有的情况放到哈希表中
- 每次取一个位
- 把 i 和 i+1 放一起,试试有没有区配的,有的话把 i 和 i+1 放一起
- 没有的话,就是 只是计 i
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);
/*
* 六种情况
IV 4 IX 9
XL 40 XC 90
CD 400 CM 9000
*/
for (int i = 0; i < c.Length; i++) { if (i + 1 < c.Length && hashtable.ContainsKey(c[i].ToString() + c[i + 1].ToString())) //如果发现两位一起能区配的话 { sum += int.Parse(hashtable.ToString() + c[i + 1].ToString()].ToString()); //获取值,HashTable的类型都是Object! i++; //跳两位 } else { sum += int.Parse(hashtable.ToString()].ToString()); } } return sum; } }
换成字典
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);
/*
* 六种情况
IV 4 IX 9
XL 40 XC 90
CD 400 CM 9000
*/
for (int i = 0; i < c.Length; i++) { if (i + 1 < c.Length && dictionary.ContainsKey(c[i].ToString() + c[i + 1])) //如果发现两位一起能区配的话 { sum += dictionary.ToString() + c[i + 1].ToString()]; //获取值,HashTable的类型都是Object! i++; //跳两位 } else { sum += dictionary.ToString()]; } } return sum; } }
以上两个例子都会进行较多的装箱拆箱,下面主要使用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; } }
文章评论