数学专题
不要纠结,干就完事了,熟练度很重要!!!多练习,多总结!!!
分治篇
LeetCode 263. 丑数
解题思路
为判断 nnn 是否满足上述形式,可以对 nnn 反复除以 2,3,52,3,52,3,5,直到 nnn 不再包含质因数 2,3,52,3,52,3,5。若剩下的数等于 111,则说明 nnn 不包含其他质因数,是丑数;否则,说明 nnn 包含其他质因数,不是丑数。
代码实现
class Solution {
public boolean isUgly(int n) {
if(n < 1){
return false;
}
int[] fac = {2, 3, 5};
for(int c : fac){
while(n%c == 0){
n = n/c;
}
}
return n==1;
}
}
LeetCode 69. x 的平方根
解题思路
二分查找的下界为 000,上界可以粗略地设定为 xxx。在二分查找的每一步中,我们只需要比较中间元素 mid 的平方与 xxx 的大小关系,并通过比较的结果调整上下界的范围。由于我们所有的运算都是整数运算,不会存在误差,因此在得到最终的答案 ans 后,也就不需要再去尝试 ans+1 了。
代码实现
class Solution {
public int mySqrt(int x) {
if(x==0){
return 0;
}
long left=1,right=x;
while(left<=right){
long mid=left+(right-left)/2;
if(mid*mid<x){
left=mid+1;
}else if(mid*mid>x){
right=mid-1;
}else{
return (int)mid;
}
}
return (int)right;
}
}
LeetCode 7. 整数反转
代码实现
public int reverse (int x) {
int res = 0;
while (x != 0) {
int c = x % 10;
//判断当前字符加入结果集是否超限
if (res > 0 && isOutMax(res, c))return 0;
if (res < 0 && isOutMin(res, c))return 0;
res = res * 10 + c;
//倒数下一位
x /= 10;
}
return res;
}
private boolean isOutMax(int target, int c) {
if (target > Integer.MAX_VALUE / 10) return true;
return target == Integer.MAX_VALUE / 10 && c > Integer.MAX_VALUE % 10;
}
private boolean isOutMin(int target, int c) {
if (target < Integer.MIN_VALUE / 10) return true;
//注意取反比较
return target == Integer.MIN_VALUE / 10 &&
(c - '0') > -(Integer.MIN_VALUE % 10);
}
LeetCode 179. 最大数
代码实现
class Solution {
public String largestNumber(int[] nums) {
int n = nums.length;
String[] ss = new String[n];
for (int i = 0; i < n; i++) ss[i] = "" + nums[i];
Arrays.sort(ss, (a, b) -> {
String sa = a + b, sb = b + a ;
return sb.compareTo(sa);
});
StringBuilder sb = new StringBuilder();
for (String s : ss) sb.append(s);
int len = sb.length();
int k = 0;
while (k < len - 1 && sb.charAt(k) == '0') k++;
return sb.substring(k);
}
}
LeetCode 166. 分数到小数
代码实现
class Solution {
public String fractionToDecimal(int numerator, int denominator) {
// 转 long 计算,防止溢出
long a = numerator, b = denominator;
// 如果本身能够整除,直接返回计算结果
if (a % b == 0) return String.valueOf(a / b);
StringBuilder sb = new StringBuilder();
// 如果其一为负数,先追加负号
if (a * b < 0) sb.append('-');
a = Math.abs(a); b = Math.abs(b);
// 计算小数点前的部分,并将余数赋值给 a
sb.append(String.valueOf(a / b) + ".");
a %= b;
Map<Long, Integer> map = new HashMap<>();
while (a != 0) {
// 记录当前余数所在答案的位置,并继续模拟除法运算
map.put(a, sb.length());
a *= 10;
sb.append(a / b);
a %= b;
// 如果当前余数之前出现过,则将 [出现位置 到 当前位置] 的部分抠出来(循环小数部分)
if (map.containsKey(a)) {
int u = map.get(a);
return String.format("%s(%s)", sb.substring(0, u), sb.substring(u));
}
}
return sb.toString();
}
}
LeetCode 204. 计数质数
解题思路
埃氏筛方法
代码实现
法一:常规方法
class Solution {
public int countPrimes(int n) {
int cnt = 0;
for (int i = 2; i < n; i++) {
if (isPrime(i)) {
cnt++;
}
}
return cnt;
}
private boolean isPrime(int num) {
int max = (int)Math.sqrt(num);
for (int i = 2; i <= max; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
}
法二:埃氏筛
class Solution {
public int countPrimes(int n) {
boolean[] isPrim = new boolean[n];
Arrays.fill(isPrim, true);
// 从 2 开始枚举到 sqrt(n)。
for (int i = 2; i * i < n; i++) {
// 如果当前是素数
if (isPrim[i]) {
// 就把从 i*i 开始,i 的所有倍数都设置为 false。
for (int j = i * i; j < n; j+=i) {
isPrim[j] = false;
}
}
}
// 计数
int cnt = 0;
for (int i = 2; i < n; i++) {
if (isPrim[i]) {
cnt++;
}
}
return cnt;
}
}
总结
本题来源于Leetcode中 归属于数学逻辑专题类型题目。
同许多在算法道路上不断前行的人一样,不断练习,修炼自己!
如有博客中存在的疑问或者建议,可以在下方留言一起交流,感谢各位!
觉得本博客有用的客官,可以给个点赞+收藏哦! 嘿嘿
喜欢本系列博客的可以关注下,以后除了会继续更新面试手撕代码文章外,还会出其他系列的文章!