zoukankan      html  css  js  c++  java
  • 数字操作题目汇总

    7、整数反转:
    给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

    示例 1:

    输入: 123
    输出: 321
     示例 2:

    输入: -123
    输出: -321
    示例 3:

    输入: 120
    输出: 21


    思路:假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1]。
    根据这个假设,如果反转后的整数溢出,则返回 0。

    先判断正负,然后看在反转过程中会不会越界,越界则返回0;

    注意:判断时用除法而不用乘法是为了避免溢出发生;

    class Solution {
    public:
        // #define INT_MAX 2147483647
        // #define INT_MIN (-INT_MAX-1)
        int reverse(int x) {
            int flag=x<0?-1:1;
            int num=0;
            while(x){
                //判断是否溢出
                if((flag==-1&&(INT_MIN/10>num))||(flag==1&&INT_MAX/10<num))return 0;
                num=num*10+x%10;
                x/=10;
            }
            return num;
        }
    };
    

      

    202. 快乐数
    编写一个算法来判断一个数 n 是不是快乐数。

    「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,
    也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。

    如果 n 是快乐数就返回 True ;不是,则返回 False 。


    思路:
    对于快乐数,难度在于计算每个位置上的数字的平方和,这里我们可以对n取余数得到n的个位,求其平方并累加,对n /10的结果用int保存,得到去除个位的n的其他位数字,
    重复上述步骤,直至其他位数字求取结果为零,得到n的各个位置的数字的平方和,重复操作直至平方和等于1。
    对于非快乐数,肯定不能进入死循环,那么肯定循环进行到一定程度,数字会和之前出现过n重复,因此我们保存每一步骤的n,
    并在得到新的n的时候判断该数字是否出现过,出现过就为非快乐数,跳出循环。

    class Solution {
    public:
        bool isHappy(int n) {
            set<int> recordN;        
            int sum = 0;
            while(n != 1){
                recordN.insert(n);
                sum = 0;
                while(n != 0){
                    //各个数字求平方和
                    sum += ((n % 10) * (n % 10));
                    n = n / 10;
                }
                //若构成死循环,则返回false
                if(recordN.find(sum) != recordN.end())
                    return false;
                n = sum;
            }
            return true;
        }
    };
    

      

    请你来实现一个 atoi 函数,使其能将字符串转换成整数。

    首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:

    • 如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
    • 假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
    • 该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。

    注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。

    在任何情况下,若函数不能进行有效的转换时,请返回 0 。

    提示:

    • 本题中的空白字符只包括空格字符 ' ' 。
    • 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231,  231 − 1]。如果数值超过这个范围,请返回  INT_MAX (231 − 1) 或 INT_MIN (−231) 。

    示例 1:

    输入: "42"
    输出: 42
    

    示例 2:

    输入: "   -42"
    输出: -42
    解释: 第一个非空白字符为 '-', 它是一个负号。
         我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
    

    示例 3:

    输入: "4193 with words"
    输出: 4193
    解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
    

    示例 4:

    输入: "words and 987"
    输出: 0
    解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
         因此无法执行有效的转换。

    示例 5:

    输入: "-91283472332"
    输出: -2147483648
    解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 
         因此返回 INT_MIN (−231) 。


    思路:是否为空判断,然后处理空格和正负号情况,然后遍历数字,字符相减转换成int
    溢出的情况下,返回INT_MIN或者INT_MAX,最后判断一下正负返回

    class Solution {
    public:
        int myAtoi(string s) {
            int len = s.length();
            if(len==0){
              return 0;
            }
     
            int i=0;
            //跳过前面空格,判断正负
            while(s[i]==' '){
                i++;
            }
             
            bool neg = false;
            //对非空和非+-号的有效数字进行处理
            if(s[i]=='-'){
                neg=true;
                i++;
            }else if(s[i]=='+'){
                i++;
            }
     
            long ans =0;
            for(;i<len;i++){
                if(s[i]>='0'&&s[i]<='9'){
                //***字符相减转换成int
                    ans = ans*10+(s[i]-'0');
                    if(ans > INT_MAX && neg) return INT_MIN;
                    if(ans > INT_MAX && !neg) return INT_MAX;
                }
                //碰到非有效数字就退出
                else{
                    break;
                }
            }
            return neg?-ans:ans;
     
    
        }
    };
    

      

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

    示例 1:

    输入: 121
    输出: true
    示例 2:

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

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


    思路:反转数字后判断两个数是不是相等,需要注意数据反转后溢出的情况,所以将反转后的类型定义为long
    或者,输入数字转化为字符串。回文数关于中心对称,只需比较对称的数是否相等即可

    class Solution {
    public:
        bool isPalindrome(int x) {
            if(x<0){
                return false;
            }
    
            int num=x;
    
            long res = 0;
    
            while(x){
                res = res*10+x%10;
                x = x/10;
            }
    
            cout<<res;
            if (res!=num){
                return false;
            }
    
            return true;
    
        }
    };
    

      

    43. 字符串相乘

    给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

    示例 1:

    输入: num1 = "2", num2 = "3"
    输出: "6"
    示例 2:

    输入: num1 = "123", num2 = "456"
    输出: "56088"
    说明:

    num1 和 num2 的长度小于110。
    num1 和 num2 只包含数字 0-9。
    num1 和 num2 均不以零开头,除非是数字 0 本身。
    不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

    思路:
    ①m位数乘以n位数的结果,最长为m+n位。

    ②在计算机中,以string标示的数字,下标i乘以下标j的结果,理应放在下标(i+j)处。

    但是,考虑到进位,需要留一位固定的answer[0]给最高位进位的数字。

    于是(i,j)乘积的临时结果temp的实际下标应该为answer[i+j+1]。

    注意,要从个位开始乘法累加,在string中是从str[str.size()-1]开始到str[0]结束。

    ③在①中可以证明,m位乘n位结果最多m+n位,因此我们申请m+n位的数组,下标最大值为m+n-1。

    在②中显然,下标i<=m-1,下标j<=n-1,则下标i+j+1<=m+n-1,恰好为数组下标的最大值。

    从两个方向获得的上界吻合,所申请空间的利用率为100%。

    模拟正常算乘法的步骤就可以,需要注意最后结果的第一个字符不能为‘0’。

    class Solution {
    public:
        string multiply(string num1, string num2) {
            if(num1 == "0" || num2 == "0")
                return "0";
            int size1 = num1.size(), size2 = num2.size();
            string str(size1 + size2, '0');
            for(int i = size1 - 1; i >= 0; i--){
                int mulflag = 0;
                int addflag = 0;
                for(int j = size2 - 1; j >= 0; j--){
                    int tmp = (num1[i] - '0') * (num2[j] - '0') + mulflag;
                    mulflag = tmp / 10;
                    tmp  = tmp % 10;
                    int tmp2 = str[i + j + 1] - '0' + tmp + addflag;
                    str[i + j + 1] = tmp2 % 10 + '0';
                    addflag = tmp2 / 10;
                }
                str[i] += mulflag + addflag;
            }
            if (str[0] == '0')
                str = str.substr(1, str.size()); 
            return str;
        }
    };
    

      

    172. 阶乘后的零
    给定一个整数 n,返回 n! 结果尾数中零的数量。

    示例 1:

    输入: 3
    输出: 0
    解释: 3! = 6, 尾数中没有零。
    示例 2:

    输入: 5
    输出: 1
    解释: 5! = 120, 尾数中有 1 个零.
    说明: 你算法的时间复杂度应为 O(log n) 。

    思路:阶乘后的零是因为5乘以一个偶数的结果,所以5的个数,决定了阶乘后零的个数。

    但是怎样查看阶乘中5的个数呢,要根据因式分子
    例如n=30,30!=1*2*3*4*5*6*7*8*9*10*...*30;
    里面有多少个为5的因式分子的,先看里面有多少个元素可以整除5,
    有5,10,15,20,25,30共6个这个6是怎么求出来的呢?6=30/5;
    然后在这六个元素里分别提取分式因子5,可以提取出六个,提取后变成1,2,3,4,5,6,然后看这六个里面有多少个元素可以整除5,6/5=1,
    所以有一个元素5还可以继续提取出一个因式分子5,这样就可以看出30!中总共包括7个因式分子5.,所以有7个零

    class Solution {
    public:
        int trailingZeroes(int n) {
            int num=0;
            while(n){
                num=num+n/5;
                n=n/5;
            }
            return num;
    
        }
    };
    

      

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

    示例:

    输入: 38
    输出: 2
    解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。
    进阶:
    你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?


    思路:常规方法,每位数字相加,如果和小于10,则直接返回,否则将和继续按位求和,直到满足条件

    class Solution {
    public:
        int addDigits(int num) {
            int res = 0;
            int sum= 0;
            while(num){
                sum=sum+num%10;
                num=num/10;
    
                if(num==0&&sum>=10){
                    num = sum;
                    sum = 0;
                }
    
    
                if(num==0&&sum<10){
                    return sum;
                }
    
            }
    
            res= sum;
    
            return res;
    
        }
    };
    

      

  • 相关阅读:
    1036 商务旅行
    4165 ​高精度求阶乘
    3117 高精度练习之乘法
    封装代理
    freemarker写select组件(三)
    VC双缓冲画图技术介绍
    JS学习十七天----工厂方法模式
    Struts2 全局结果集
    HDU 1730 Northcott Game
    C++ STL:vector
  • 原文地址:https://www.cnblogs.com/Allen-rg/p/13877102.html
Copyright © 2011-2022 走看看