加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数

发布时间:2020-12-16 01:17:20 所属栏目:百科 来源:网络整理
导读:各位相加 给定一个非负整数? num ,反复将各个位上的数字相加,直到结果为一位数。 示例: 输入: 38 输出: 2 解释: 各位相加的过程为: 3 + 8 = 11 , 1 + 1 = 2 。 由于 2 是一位数,所以返回 2 。 进阶: 你可以不使用循环或者递归,且在 O(1) 时间复杂度内解

各位相加

给定一个非负整数?num,反复将各个位上的数字相加,直到结果为一位数。

示例:

输入: 38
输出: 2 
解释: 各位相加的过程为:3 + 8 = 11,1 + 1 = 2。 由于 2 是一位数,所以返回 2

进阶:
你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?

题目地址?https://leetcode-cn.com/problems/add-digits/

代码模板

public class Solution {
    int AddDigits(int num) {

    }
}

?

测试数据

输入 1
输出 

输入 1019988885

?

笔者的方法:

使用了while循环,除一次计算一次,原始数和各位数和同时变化。时间在70ms内。

        static int Csum( num)
        {
            if (num < 10)       //小于10的数直接返回
                return num;
            int shi = 0;        记录个位数相加
            while (num > 0)
            {
                if (num >= )
                {
                    shi += num % ;
                    num = num / ;
                }
                else )
                {
                    shi += num;
                    num = num / ;
                }

                if (shi >= 10) shi = shi % 10 + shi / ;    //超过10的个位数重新变化
            }
             shi;
        }

方法二??弃九验算法

同样在 60-70ms

 num) {
        if(num==)
            return ;
        if(num%9==9return num%;
    }
}

?


整数反转

给出一个 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左右

    Solution
    {
        int Reverse( x)
        {

            int num = ;
            while (x != int i = x % ;
                x = x / ;
                C# int32 范围 [-2147483647~2147483647]
                if (num > int.MaxValue /  )
                    if (num < int.MinValue / )
                    ;

                num = num * 10 + i;
            }
             num;
        }
    }

回文数

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

题目地址:https://leetcode-cn.com/problems/palindrome-number

示例 1:

输入: 121
输出: true

示例?2:

输入: -121
输出: false
解释: 从左向右读,为 -121 。 从右向左读,为 121- 。因此它不是一个回文数。

示例 3:

输入: 10
输出: false
解释: 从右向左读,为 01 。因此它不是一个回文数。

进阶:

你能不将整数转为字符串来解决这个问题吗?

代码模板

bool IsPalindrome( x) {
        
    }
}

?

笔者的代码

运行时间在120ms左右,笔者的思路是:如果一个数字的反序还是等于这个数,那么这个数就是回文数。

以下代码无法解决反序后可能溢出,可以利用上一题的代码进行溢出检查。

当然,一个int类型的数,如果是回文,那么他的反序肯定不会溢出,反之其反序发生溢出则肯定不是回文数。

     x)
        {
            if (x < 0) return falseint xx = x;
            0;  x的反序
            while (xx != )    //求反序
            {
                int i = xx % ;
                xx = xx / ;
                num = num * if (x == num)       如果x的反序num==x,那么这个数字是回文数
                true;

            else
                ;

        }
    }

?加try-catch,耗时增加 10~20ms

            try { 
             i;
            }
            }
            catch
            {
                ;
            }

?

官方这道题给出了示例代码,耗时120ms左右,思路是只反序一半,反序后的原始数、反序一半的数进行比较,也就不用检查溢出。

 x) {
         特殊情况:
         如上所述,当 x < 0 时,x 不是回文数。
         同样地,如果数字的最后一位是 0,为了使该数字为回文,
         则其第一位数字也应该是 0
         只有 0 满足这一属性
        if(x < 0 || (x % 10 == 0 && x != )) {
            ;
        }

        int revertedNumber = while(x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % ;
            x /=  当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
         例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
         由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
        return x == revertedNumber || x == revertedNumber/;
    }
}

别人用字符串方式进行判断(虽然题目说不能用string),耗时150-180ms,不太稳定

    string str = x.ToString();
            for (int i = 0; i < str.Length / 2; ++i)
            {
                if (str[i] != str[str.Length - 1 - i])
                {
                    ;
                }
            }
            ;
        }
    }

罗马数字转整数

罗马数字包含以下七种字符:?I,?V,?X,?LCD?和?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
    int RomanToInt(string s)
        {
            char[] c = s.ToCharArray();         将其转为字符数组
            int sum = 0;                        
            Hashtable hashtable = new Hashtable();
            7个基本单位
            hashtable.Add("I",1)">);
            hashtable.Add(V5XL50C100D500M1000);
            加上6种情况
            hashtable.Add(IV4IXXL40XC90CD400CM900);

/*
* 六种情况
IV 4 IX 9
XL 40 XC 90
CD 400 CM 9000
*/

            0; i < c.Length; i++if (i + 1 < c.Length && hashtable.ContainsKey(c[i].ToString() + c[i + 1].ToString()))     如果发现两位一起能区配的话
                {
                    sum += int.Parse(hashtable[c[i].ToString() + c[i + 1].ToString()].ToString());        获取值,HashTable的类型都是Object!
                    i++;                                                                                    跳两位
                }
                else
                {
                    sum += .Parse(hashtable[c[i].ToString()].ToString());
                }

            }
             sum;
        }
    }

?换成字典

    
            Dictionary<string,int> dictionary = new Dictionary<int>();
            7个基本单位
            dictionary.Add();
            dictionary.Add(加上6种情况
            dictionary.Add(1 < c.Length && dictionary.ContainsKey(c[i].ToString() + c[i + 1]))                     {
                    sum += dictionary[c[i].ToString() + c[i + 1].ToString()];        
                {
                    sum += dictionary[c[i].ToString()];
                }

            }
             sum;
        }
    }

?以上两个例子都会进行较多的装箱拆箱,下面主要使用if-else,switch,空间花销较大,但是如果测试例子较多,进行大量计算,时间会相对少一点。

    

            0; i < s.Length; i++1 < s.Length)       如果后面还有别的字符
                {
                    if (s[i] == '')
                    {
                        int a = ;
                        switch (s[i + 1])     "i%"
                        {
                            case ': a = 4; i++; break;
                            9; i++; default: a = 1; ;
                        }
                        sum += a;
                    }
                    ;

                        "X%"
40; i++; 90; i++; 10; 400; i++; 900; i++; 100; 
                    {
                        switch (s[i])
                        {5; ;50; 500; 1000;  a;
                    }
                }

                
                {
                    ;
                     (s[i])
                    {
                        ;
                    }
                    sum += a;
                }
            }

             sum;
        }
    }

?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读