LeetCode刷题:其他

模拟乘法

不能直接用Long,问题在于会出现溢出的情况。
只能手动模拟相乘的情况
在这里插入图片描述在这里插入图片描述

class Solution {
    
    
    public String multiply(String num1, String num2) {
    
    
        if (num1.equals("0") || num2.equals("0")) {
    
    
            return "0";
        }
        String ans = "0";
        int m = num1.length(), n = num2.length();
        for (int i = n - 1; i >= 0; i--) {
    
    
            StringBuffer curr = new StringBuffer();
            int add = 0;
            for (int j = n - 1; j > i; j--) {
    
    
                curr.append(0); // 模拟× 10 的场景
            }
            int y = num2.charAt(i) - '0';
            for (int j = m - 1; j >= 0; j--) {
    
    
                int x = num1.charAt(j) - '0';
                int product = x * y + add;
                curr.append(product % 10);
                add = product / 10;
            }
            if (add != 0) {
    
    
                curr.append(add % 10);
            }
            ans = addStrings(ans, curr.reverse().toString());
        }
        return ans;
    }
 
    public String addStrings(String num1, String num2) {
    
    
        int i = num1.length() - 1, j = num2.length() - 1, add = 0;
        StringBuffer ans = new StringBuffer();
        while (i >= 0 || j >= 0 || add != 0) {
    
     // add直接在这里处理
            int x = i >= 0 ? num1.charAt(i) - '0' : 0; // 防止越位以及最后判断谁越位
            int y = j >= 0 ? num2.charAt(j) - '0' : 0;
            int result = x + y + add;
            ans.append(result % 10); // 本次添加余数
            add = result / 10; // 留给下次的是本次的结果
            i--;
            j--;
        }
        ans.reverse();
        return ans.toString();
    }
}

更直接的:

BigDecimal n1 = new BigDecimal(num1);
BigDecimal n2 = new BigDecimal(num2);
BigDecimal res = n1.multiply(n2);
return res.toPlainString();

149.直线上最多的点树

在这里插入图片描述
Y=kx + b
求出所有的kb,两个点决定一个kb,n的平方的遍历
然后枚举哪些坐标满足计算公式
求出最大的数目

模拟幂次

https://leetcode-cn.com/problems/powx-n/
在这里插入图片描述

class Solution {
    
    
    public double myPow(double x, int n) {
    
    
        long N = n;
        return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
    }
 
    public double quickMul(double x, long N) {
    
    
        if (N == 0) {
    
    
            return 1.0;
        }
        double y = quickMul(x, N / 2);
        return N % 2 == 0 ? y * y : y * y * x;
    }
}

原地hash

https://leetcode-cn.com/problems/find-all-duplicates-in-an-array/
在这里插入图片描述解题思路
要不使用额外内存空间,则只能原地修改数组元素来标记是否访问过
原理:如果是相同的元素,那么以他们为索引的元素值一定是同一个值,因此可以修改该值来标记是否被访问过
注意:既要原地修改元素,就不能影响其自身作为索引的访问,那么只有一种办法,那就是将该元素取反,或者加减某个数,在访问的时候,再通过取正或者加减某个数还原回来

利用index与a[index]之间的关系
即取该元素值n,然后将a[abs(n)]取反。
如果下次遇到发现a[abs(n)]是负数,说明之前访问过。直接加入结果集。

位运算

有点类似hash的思路,用位来表征状态

求子集的题目:
https://leetcode-cn.com/problems/subsets/solution/zi-ji-by-leetcode-solution/
在这里插入图片描述在这里插入图片描述核心思路:

  1. 暴力搜索
  2. 用位来表示对应位置的数组是否启用

核心代码:

扫描二维码关注公众号,回复: 13007620 查看本文章
for (int mask = 0; mask < (1 << n); ++mask) {
    
    
            t.clear();
            for (int i = 0; i < n; ++i) {
    
    
                if ((mask & (1 << i)) != 0) {
    
    
                    t.add(nums[i]);
                }
            }
            ans.add(new ArrayList<Integer>(t));
        }

代码:

class Solution {
    
    
    List<Integer> t = new ArrayList<Integer>();
    List<List<Integer>> ans = new ArrayList<List<Integer>>();
 
    public List<List<Integer>> subsets(int[] nums) {
    
    
        int n = nums.length;
        for (int mask = 0; mask < (1 << n); ++mask) {
    
    
            t.clear();
            for (int i = 0; i < n; ++i) {
    
    
                if ((mask & (1 << i)) != 0) {
    
    
                    t.add(nums[i]);
                }
            }
            ans.add(new ArrayList<Integer>(t));
        }
        return ans;
    }
}

暴力解法:小问题的解构成大问题的解
在这里插入图片描述

在已经有的集合上新加入元素变成新的集合再扔进去。
在这里插入图片描述

191.位1的个数

https://leetcode-cn.com/problems/number-of-1-bits/
在这里插入图片描述

要点:

  1. 32位以内,即<<1的操作最多32次

https://leetcode-cn.com/problems/number-of-1-bits/solution/wei-1de-ge-shu-by-leetcode/

public int hammingWeight(int n) {
    
    
    int bits = 0;
    int mask = 1;
    for (int i = 0; i < 32; i++) {
    
    
// 最多32次
        if ((n & mask) != 0) {
    
    
            bits++; // 为1的位数
        }
        mask <<= 1;
    }
    return bits;
}

与运算符用符号“&”表示,其使用规律如下:
两个操作数中位都为1,结果才为1,否则结果为0,例如下面的程序段。
129&128 = 128。 “a”的值是129,转换成二进制就是10000001,而“b”的值是128,转换成二进制就是10000000。根据与运算符的运算规律,只有两个位都是1,结果才是1,可以知道结果就是10000000,即128。

排序有关记录

  1. 任务调度器:执行有冷却时间命令的最短时间。621
    https://leetcode-cn.com/problems/task-scheduler/
    解法一:排序。排序是为了确认优先级,每轮第一个消除的是最大值的元素。
  2. 合并公共区间:https://leetcode-cn.com/problems/merge-intervals/solution/zhen-dui-xin-shou-jian-ji-yi-dong-de-ti-jie-liang-/
    排序加比较后的合并。
    另一种解法:boolean数组做标记,这种解法无法处理一种情况:[1,4][5,6],这种不算做有公共区间。
  3. 两个有序的自定义链表合并:https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode/
  4. 原地排序的双指针法: https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/submissions/

猜你喜欢

转载自blog.csdn.net/weixin_38370441/article/details/115251343