数学逻辑专题


不要纠结,干就完事了,熟练度很重要!!!多练习,多总结!!!

分治篇

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中 归属于数学逻辑专题类型题目。
同许多在算法道路上不断前行的人一样,不断练习,修炼自己!
如有博客中存在的疑问或者建议,可以在下方留言一起交流,感谢各位!

觉得本博客有用的客官,可以给个点赞+收藏哦! 嘿嘿

喜欢本系列博客的可以关注下,以后除了会继续更新面试手撕代码文章外,还会出其他系列的文章!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值