解法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