zoukankan      html  css  js  c++  java
  • 数组:实现整数的数字反转, 位运算 (Leetcode 07 / 08 / 190 / 191 / 65)

     

     

     

     

      

     

     解法1代码

    /**
     暴力解法:
     1.整数转字符串,再转字符数组
    2.反向遍历字符数组,并将元素存储到新数组中
     3.将新数组转成字符串,再转成整数输出
     注意事项:
     1.边界问题
       2.数组索引越界
             数值溢出边界:溢出则返回0
      细节问题
        1.首位不为0
        2.符号处理
      
    @param
    x 指定整数 @return 反转后的整数,或0 */

    public int reverse(int x) { if (x == Integer.MIN_VALUE || x == Integer.MAX_VALUE) { // 整数类型的最小值的绝对值 比 最大值的绝对值 大1 return 0; }
    int sign = (x > 0) ? 1 : -1; // 符号 x = (x < 0) ? -x : x; // 无论正负,都当成正数
    // 1.整数转字符串,再转字符数组 String str = String.valueOf(x); char[] chars = str.toCharArray();
    // 2.反向遍历字符数组,并将元素存储到新数组中 int len = chars.length; char[] array = new char[len];
    for (int i = 0; i < len; i++) { // 遍历新数组 array[i] = chars[len - 1 - i]; }
    // 3.将新数组转成字符串,再转成整数输出 long value = Long.valueOf(String.valueOf(array)); boolean b = (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE); int result = b ? 0 : (int)value; // 数值越界:溢出则返回0 return result * sign; }

     

     

     代码

    /**
    思路:
    1.整数转字符串,再转字符数组
    2.交换首位(start)和末位(end)数字
    3.循环操作:依次交换第二(start++)和倒数第二个(end--)
    直到数组剩下1个或0个元素
    4.将原数组转成字符串,再转成整数输出
    注意事项:
        1.边界问题
          <1>数组索引越界:数组长度为偶数,反转完成标志为start>end;
                        为奇数时,反转完成标志为start==end
          <2>数值溢出边界:溢出则返回0
        2.细节问题
          <1>首位不为0
          <2>符号处理
         @param x 指定整数
         @return 反转后的整数,或0
    */
    public int reverse(int x) {
      if (x == Integer.MIN_VALUE || x == Integer.MAX_VALUE) {
        // 整数类型的最小值的绝对值 比 最大值的绝对值 大1
        return 0;
    } int sign = (x > 0) ? 1 : -1; // 符号 x = (x < 0) ? -x : x; // 无论正负,都当成正数
    // 1.整数转字符串,再转字符数组 String str = String.valueOf(x); char[] chars = str.toCharArray();
    // 2.交换首位(start)和末位(end)数字 // 3.循环操作:依次交换第二(start++)和倒数第二个(end--) int start = 0, end = chars.length - 1; while (start < end) { // 反转完成的标志:start >= end // 交换两端等距离的元素 char temp = chars[start]; chars[start] = chars[end]; chars[end] = temp; start++; end--; }
    // 4.将原数组转成字符串,再转成整数输出 long value = Long.valueOf(String.valueOf(chars)); boolean b = (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE); int result = b ? 0 : (int)value; return result * sign; }

     

     最优解代码

    /**
     最优解法 数学解法思路:
      1.尝试拿个位数字
        对10取模运算得到个位数字
      2.让每一位数字变成个位数字
        先除以10,再对10取模得到十位数字
      循环上述操作

    3.将每一位数字计算累加 将上次累加结果*10 + 新数字 注意事项: <1>边界问题:    1. 从低位到高位处理,最高位结束 终止条件:最高位 / 10 == 0 或 最高位 % 10 == 最高位
        2. 数值溢出边界:溢出则返回0 用long类型存放,溢出int则返回0 新整数补充最后一位前判断溢出
     <2>细节问题: 1.首位不为0 2.符号处理
    @param x 指定整数 @return 反转后的整数,或0 */

    public int reverse(int x) { if (x == Integer.MIN_VALUE || x == Integer.MAX_VALUE) { // 整数类型的最小值的绝对值 比 最大值的绝对值 大1 return 0; } int sign = (x > 0) ? 1 : -1; // 符号 x = (x < 0) ? -x : x; // 无论正负,都当成正数 int result = 0; // 返回结果
    // 1.尝试拿个位数字:对10取模运算 // 2.让每一位数字变成个位数字:先除以10,再对10取模得到十位数字 int last = 0; // 末位 while ((last = x % 10) != x) { // 3.将每一位数字计算累加:将上次累加结果*10 + 新数字 result = result * 10 + last; x /= 10; } if (last != 0) { // 此时last是最高位,单独处理 long re = result; re = re * 10 + last; if (re > Integer.MAX_VALUE || re < Integer.MIN_VALUE) { result = 0; } else { result = (int)re; } } return result * sign; // 返回前进行符号处理
    }

     

     

     

     Leetcode 8 - 版本1 (不考虑负数)

    //题目说的输入是整形字符串,所以不用考虑非法整数问题,整数越界问题,是一道简化版atoi. 
    //考查算法基本功。
    
    public int myAtoi(String str) {
        int len = str.length();
        char[] charArray = str.toCharArray();
        int index=0;
    
        // 将数字字符进行转换
        int res = 0;
        while (index < len) {
            char currChar = charArray[index];
            res = res * 10 + (currChar - '0');
            index++;
        }
        return res;
    }

     Leetcode 8 - 版本2 (考虑负数)

    class Solution {
        public int myAtoi(String str) {
            
            //判断传入字符串的有效性
            if(str==null || str.length() == 0) {
                return 0;
            }
    
            int len = str.length();
            double sum = 0;
            int sign = 1;
            int j = 0;
    
            //剔除空格
            while(str.charAt(j) == ' '){
                j++;
            }
                
            //判断正数和负数
            if(str.charAt(j) == '+') {
                sign = 1;
                j++;
            }else if(str.charAt(j) == '-') {
                sign = -1;
                j++;
            }
    
            for(int i=j;i<len;i++) {
                char current = str.charAt(i);
                if(current >= '0' && current <= '9') {
                    sum = sum*10 + (int)(current - '0');
                } else {
                    break;//碰到非数字,退出转换
                }
            }
            sum = sum*sign;
    
            //判断结果的数值范围
            if (sum > Integer.MAX_VALUE) {
                sum = Integer.MAX_VALUE;
            } else if (sum < Integer.MIN_VALUE) {
                sum = Integer.MIN_VALUE;
            }
            return (int)sum;
        }
    }

    Leetcode 190 - 颠倒二进制位

      颠倒给定的 32 位无符号整数的二进制位。

      示例 1:

        输入: 00000010100101000001111010011100
        输出: 00111001011110000010100101000000
        解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596,
        因此返回 964176192 ( 其二进制表示形式为 00111001011110000010100101000000 )

      示例 2:
        输入:11111111111111111111111111111101
        输出:10111111111111111111111111111111
        解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293,
        因此返回 3221225471 ( 其二进制表示形式为 10111111111111111111111111111111 )

      提示:

      请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
      在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数 -1073741825。

      代码 -  用位运算反转二进制数

    public class Solution {
        public int reverseBits(int n) {
            int result = 0;
            for (int i = 0; i < 32; i++) {
                result += n & 1;
                n >>= 1;
                if(i != 31){
                    result <<= 1;
                }
            }
            return result;
        }
    }
    
    // 为了方便理解, 可以拿纸笔模拟 1010 转化为 0101 的过程

    题目:

    给你一个整数 n,请你帮忙计算并返回该整数「各位数字之积」与「各位数字之和」的差。

    示例 1:
      输入:n = 234
      输出:15
        解释:
          各数之积 = 2 * 3 * 4 = 24
          各数之和 = 2 + 3 + 4 = 9
          结果 = 24 - 9 = 15

    示例 2:
      输入:n = 4421
      输出:21
        解释:
          各数之积 = 4 * 4 * 2 * 1 = 32
          各数之和 = 4 + 4 + 2 + 1 = 11
          结果 = 32 - 11 = 21

    提示:
    1 <= n <= 10^5

    代码

    class Solution {
        public int subtractProductAndSum(int n) {
            int muti = 1;
            int sum = 0;
            while(n!=0){
                muti *= n%10;
                sum += n%10;
                n /= 10;
            } 
            return muti - sum;
        }
    }

    Leetcode 65 

    验证给定的字符串是否可以解释为十进制数字。

    例如:

      "0" => true
      " 0.1 " => true
      ".1 " => true
      "3." => true
      "abc" => false
      "1 a" => false
      "2e10" => true
      " -90e3 " => true
      " 1e" => false
      "e3" => false
      " 6e-1" => true
      " 99e2.5 " => false
      "53.5e93" => true
      " --6 " => false
      "-+3" => false
      "95a54e53" => false

      说明: 我们有意将问题陈述地比较模糊。在实现代码之前,你应当事先思考所有可能的情况。

      这里给出一份可能存在于有效十进制数字中的字符列表:

        数字: 0-9
        指数:"e"
        正/负号: "+" "-"
        小数点: "."
      当然,在输入中,这些字符的上下文也很重要。

    代码

    /*
    这题看着很麻烦,实际上也有些麻烦,但只要把注意的点都搞清楚,其实代码结构是很简单的
    
    先设定numSeen,dotSeen和eSeen三种boolean变量,分别代表是否出现数字、点和E
    然后遍历目标字符串
    1.判断是否属于数字的0~9区间
    2.遇到点的时候,判断前面是否有点或者E,都需要return false
    3.遇到E的时候,判断前面数字是否合理,是否有E,并把numSeen置为false,防止E后无数字
    4.遇到-+的时候,判断是否是第一个,如果不是第一个判断是否在E后面,都不满足则return false
    5.其他情况都为false
    最后返回numSeen的结果即可
    */
    
    class Solution {
        public boolean isNumber(String s) {
            if (s == null || s.length() == 0) return false;
            boolean numSeen = false;
            boolean dotSeen = false;
            boolean eSeen = false;
    
            char arr[] = s.trim().toCharArray();
            for (int i = 0; i < arr.length; i++) {
                if (arr[i] >= '0' && arr[i] <= '9') {
                    numSeen = true;
                } else if (arr[i] == '.') {
                    if (dotSeen || eSeen) {
                        return false;
                    }
                    dotSeen = true;
                } else if (arr[i] == 'E' || arr[i] == 'e') {
                    if (eSeen || !numSeen) {
                        return false;
                    }
                    eSeen = true;
                    numSeen = false;
                } else if (arr[i] == '+' || arr[i] == '-') {
                    if (i != 0 && arr[i - 1] != 'e' && arr[i - 1] != 'E') {
                        return false;
                    }
                } else {
                    return false;
                }
            }
            return numSeen;
        }
    }

    Leetcode 191

    编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量

    示例 1:

      输入:00000000000000000000000000001011

      输出:3

      解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

    提示:

      • 请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
      • 在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。


    思路1:

    class Solution(object):
        def hammingWeight(self, n):
            ans = 0
            # 一般整形为32位
            for i in range(32):
                ans += n&1
                n >>= 1
            return ans
    原文链接:https://zhuanlan.zhihu.com/p/82417902

    思路2:不断减1与运算

      对于只有一个bit位为1的值来说其与其本身减1的值与运算后必为0;
      该思路一般化后对于任意的数,只要不断将其与其本身减1后的值与运算直至为0即可得到bit位为1的数量;

    代码:

    class Solution {
    
        // you need to treat n as an unsigned value
        public int hammingWeight(int n) {
            int count = 0;
            while (n != 0) {
                n &= (n - 1);
                count++;
            }
            return count;
        }
    }
    // 为了方便理解, 可以拿纸笔模拟 1001 的计算过程
    // 原文链接:https://www.cnblogs.com/izhoujie/p/12819870.html
  • 相关阅读:
    VUE vue和element框架搭配实现导航跳转,底部导航跳转页面
    【HDFS篇14】HA高可用 --- Federation架构设
    【HDFS篇13】HA高可用 --- YARN-HA集群配置
    【HDFS篇12】HA高可用 --- HDFS-HA集群配置
    【HDFS篇11】HA高可用
    【HDFS篇10】DataNode相关概念
    【HDFS篇09】集群安全模式
    【HDFS篇08】NameNode故障处理
    【HDFS篇07】NameNode和SecondearyNameNode
    【HDFS篇06】HDFS数据读写流程
  • 原文地址:https://www.cnblogs.com/JasperZhao/p/15024679.html
Copyright © 2011-2022 走看看