力扣刷题记录_数学(自学)

1、计数质数(力扣204)

//1.暴力解法(超出时间限制)
    public static int countPrimes(int n) {
        int count = 0;
        for (int i = 2; i < n; i++) {
            if(isPrimes(i)){
                count ++;
            }
        }
        return count;
    }

    public static boolean isPrimes(int num){
        //如果说num=x*y,则在遍历过程中,x和y只需要利用一个就好
        //例如:6=2*3,遍历过2就不用遍历3了
        //因为x和y中的较小值必定在[2,根号下num]范围内,枚举[2,根号下num]即可
        for (int i = 2; i * i <= num; i++) {
            if (num % i == 0){
                return false;
            }
        }
        return true;
    }

//2.埃氏筛
    public static int countPrimes2(int n) {

        int[] isPrime = new int[n];
        Arrays.fill(isPrime,1);

        int count = 0;
        for (int i = 2; i < n; i++) {
            if (isPrime[i] == 1){
                count ++;
                //注意i * i的取值
                if ((long)i * i < n){
                    for (int j =  i * i; j < n; j+=i) {
                        isPrime[j] = 0;
                    }
                }
            }
        }
        return count;
    }

2、七进制数(力扣504)

//1.先%再/
    public String convertToBase7(int num) {
        if(num == 0) return "0";

        StringBuilder sb = new StringBuilder();
        int cur = num < 0 ? -num : num;
        while(cur > 0){
            sb.append(cur % 7);
            cur /= 7;
        }
        if(num < 0) sb.append("-");
        return sb.reverse().toString();
    }

3、数字转换为十六进制数(力扣405)

//1.利用进制转换规律
    /*
     * 使用无符号右移 >>>
     * */
    public static String toHex(int num) {

        StringBuilder sb = new StringBuilder();
        char[] arr = "0123456789abcdef".toCharArray();
        if (num ==0) return "0";
        while (num != 0){
            //计算num二进制的后四位表示的十进制数的大小
            int temp = num & 15;
            sb.append(arr[temp]);
            //二进制->16进制,每四位二进制转换为一位16进制
            num = num >>> 4;
        }
        return sb.reverse().toString();
    }

4、Excel表列名称(力扣168)

public String convertToTitle(int columnNumber) {
        StringBuilder sb = new StringBuilder();
            while(columnNumber > 0){
                int len = columnNumber % 26;
                //特别注意这一步,因为转换不是从0开始的
                if(len == 0){
                    len = 26;
                    columnNumber -=1;
                }
                sb.append((char)('A' + len - 1));
                columnNumber /= 26;
            }
            return sb.reverse().toString();
    }

//2.直接减1
    public static String convertToTitle(int columnNumber) {

        StringBuilder sb = new StringBuilder();
        while (columnNumber > 0){
            columnNumber --;
            sb.append((char)('A' + columnNumber % 26));
            columnNumber /= 26;
        }
        return sb.reverse().toString();
    }

5、阶乘后的零(力扣172)

//1.找规律
    /*
     * 找到规律,输入n,表示有n个数,每隔5个数出现一个5,
     * 每隔25个数出现2个5,每隔125个数出现3个5...
     * */
    public static int trailingZeroes(int n) {

        int count = 0;
        //先求间隔为5的5的数量,再加上间隔为25的数量,再加上...
        while (n >= 5){
            count += (n / 5);
            n /= 5;
        }
        return count;
    }

6、二进制求和(力扣67)

//1.位运算
    public static String addBinary(String a, String b) {

        int m = a.length() - 1, n = b.length() - 1;
        StringBuilder sb = new StringBuilder();

        int count = 0;
        //循环相加两个字符串相同长度的低位数部分
        while (m >= 0 && n >= 0) {
            int sum = count;
            sum += a.charAt(m--) - '0';
            sum += b.charAt(n--) - '0';
            //进位
            count = sum / 2;
            //当前位的值
            sb.append(sum % 2);
        }
        // 如果 a 还没遍历完成(a串比b串长),则继续遍历添加 a 的剩余部分
        while (m >= 0){
            int sum = count + a.charAt(m--) - '0';
            count = sum / 2;
            sb.append(sum % 2);
        }
        // 如果 b 还没遍历完成(b串比a串长),则继续遍历添加 b 的剩余部分
        while (n >= 0){
            int sum = count + b.charAt(n--) - '0';
            count = sum / 2;
            sb.append(sum % 2);
        }
        //如果count不等于0 还有个进位数没加进去,需要补充
        if (count == 1){
            sb.append(count);
        }
        //反转字符串获得正常结果
        return sb.reverse().toString();
    }

7、字符串相加(力扣415)

//1.思路很简单(只不过是十进制)
    public static String addStrings(String num1, String num2) {

        StringBuilder sb = new StringBuilder();
        int m = num1.length() - 1,n = num2.length() - 1;
        int count = 0;
        while (m >= 0 && n >= 0){
            int sum = count;
            sum += num1.charAt(m--) - '0';
            sum += num2.charAt(n--) - '0';
            count = sum / 10;
            sb.append(sum % 10);
        }

        while (m >= 0) {
            int sum = count + num1.charAt(m--) - '0';
            count = sum / 10;
            sb.append(sum % 10);
        }

        while (n >= 0) {
            int sum = count + num2.charAt(n--) - '0';
            count = sum / 10;
            sb.append(sum % 10);
        }

        if (count == 1){
            sb.append(1);
        }
        return sb.reverse().toString();
    }
//2. 1的简化版
    public static String addStrings2(String num1, String num2) {

        int m = num1.length() - 1,n = num2.length() - 1;
        StringBuilder sb = new StringBuilder();
        int count = 0;
        //只要满足以下条件,都可以计算
        while (m >= 0 || n >= 0 || count != 0){
            //注意下面这一步
            int sum1 = m >= 0 ? num1.charAt(m--) - '0': 0;
            int sum2 = n >= 0 ? num2.charAt(n--) - '0': 0;
            int sum = sum1 + sum2 + count;
            count = sum / 10;
            sb.append(sum % 10);
        }
        return sb.reverse().toString();
    }

8、最少移动次数使数组元素相等 II(力扣462)

//1.把每个元素都变为中位数即可
    /*
    * 假如数组长度为奇数2n+1 则中位数两边各有n个数
    * 设左边所有数和中位数的差值和为x 右边所有数和中位数的差值和为y
    * 则所有需要移动的次数为x+y 如果不选择中位数 例如选择中位数-1
    * 这样总的移动次数就变成了 >= ((x-n) + (y+n) + 1) 最好的情况下比中位数大1
    * 如果数组长度是偶数 有两个中位数 选择两个中位数的任何一个或
    * 者两个中位数的平均数 都是可以的
    * */
    public static int minMoves2(int[] nums) {

        int len = nums.length;
        Arrays.sort(nums);
        //选择中位数
        int midNum = nums[len / 2];

        int max = 0;
        for (int i = 0; i < len; i++) {
            max += Math.abs(nums[i] - midNum);
        }
        return max;
    }

9、多数元素(力扣169)

//1.排完序取中间即可
    public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length / 2];
    }
//2.摩尔投票法
    /*
    * 摩尔投票法:核心就是对拼消耗。
    玩一个诸侯争霸的游戏,假设你方人口超过总人口一半以上,
    并且能保证每个人口出去干仗都能一对一同归于尽。最后还有人活下来的国家就是胜利。
    那就大混战呗,最差所有人都联合起来对付你(对应你每次选择作为计数器的数都是众数)
    ,或者其他国家也会相互攻击(会选择其他数作为计数器的数),但是只要你们不要内斗,
    最后肯定你赢。最后能剩下的必定是自己人。
    * */
    public int majorityElement2(int[] nums) {
        int count = 0,maxNum = 0;
        for(int i = 0;i < nums.length;i ++){
            if(count == 0){
                maxNum = nums[i];
            }

            if(nums[i] == maxNum){
                count ++;
            }else{
                count --;
            }
        }
        return maxNum;
    }
//3.哈希表(单独写一个)
    public static int majorityElement3(int[] nums) {

        //注意使用哈希表记录次数的写法
        Map<Integer,Integer> map = new HashMap<>();
        for (int i : nums){
            if (!map.containsKey(i)){
                map.put(i,1);
            }
            map.put(i,map.get(i) + 1);
        }

        int maxNum = 0,maxCount = 0;
        //哈希表的遍历方法
        for (Map.Entry<Integer,Integer> entry : map.entrySet()){
            if (entry.getValue() > maxCount){
                maxNum = entry.getKey();
                maxCount = entry.getValue();
            }
        }
        return maxNum;
    }

10、 3 的幂(力扣326)

//1.二分法
    public static boolean isPowerOfThree(int n) {

        //看n是否是3的幂次
        long left = 0,right = n,mid,guessNum;
        while (left <= right){
            mid = (left + right) >> 1;
            guessNum = (long) Math.pow(3, mid);
            if (guessNum == n){
                return true;
            }else if (guessNum < n){
                left = mid + 1;
            }else{
                right = mid - 1;
            }
        }
        return false;
    }
//2.找规律
    public static boolean isPowerOfThree2(int n) {

        int count = 2;
        while (n >= 3){
            n -= count;
            count *= 3;
        }
        return n == 1;
    }
//3.迭代法
    public static boolean isPowerOfThree3(int n) {

        if (n < 1){
            return false;
        }
        //说明n是3的倍数
        while (n % 3 == 0){
            n /= 3;
        }
        return n == 1;
    }
//4.找规律
    public static boolean isPowerOfThree4(int n) {
        //int类型中最大的3的幂次为1162261467
        return n > 0 && 1162261467 % n == 0;
    }

11、 除自身以外数组的乘积(力扣238)

//1.(分为左右两部分,分别计算)降低时间复杂度
    public static int[] productExceptSelf(int[] nums) {

        int len = nums.length;
        int[] res = new int[len];

        //res[i]表示i左边的数的乘积
        res[0] = 1;
        for (int i = 1; i < len; i++) {
            res[i] = nums[i - 1] * res[i - 1];
        }

        //乘完左边乘右边
        int right = 1;
        for (int i = len - 1; i >= 0 ; i--) {
            res[i] = res[i] * right;
            right *= nums[i];
        }
        return res;
    }

12、 三个数的最大乘积(力扣628)

/*
      1.如果数组中全是非负数,则排序后最大的三个数相乘即为最大乘积;
      2.如果全是非正数,则最大的三个数相乘同样也为最大乘积。

      3.如果数组中有正数有负数,则最大乘积既可能是三个最大正数的乘积,
        也可能是两个最小负数(即绝对值最大)与最大正数的乘积。
    */
    //1.先排序
    public static int maximumProduct(int[] nums) {

        Arrays.sort(nums);
        int len = nums.length;
        return Math.max(nums[len - 1] * nums[len - 2] * nums[len - 3], nums[0] * nums[1] * nums[len - 1]);
    }
//2.线性扫描
    /*
    在方法一中,我们实际上只要求出数组中最大的三个数以及最小的两个数,
    因此我们可以不用排序,用线性扫描直接得出这五个数。
     */
    public static int maximumProduct2(int[] nums) {

        //min1:最小;min2:第二小
        int min1 = Integer.MAX_VALUE,min2 = Integer.MAX_VALUE;
        int max1 = Integer.MIN_VALUE,max2 = Integer.MIN_VALUE,max3 = Integer.MIN_VALUE;

        for (int i : nums){

            if (i < min1){
                min2 = min1;
                min1 = i;
            }else if (i < min2){
                min2 = i;
            }

            if (i > max1){
                max3 = max2;
                max2 = max1;
                max1 = i;
            }else if (i > max2){
                max3 = max2;
                max2 = i;
            }else if (i > max3){
                max3 = i;
            }

        }
        return Math.max(max1*max2*max3,min1*min2*max1);
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值