数组:实现整数的数字反转, 位运算 (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
原文地址:https://www.cnblogs.com/JasperZhao/p/15024679.html