Day09 有关数学运算的一些常见算法
1、判断两个数相除的结果是否是无限循环小数。
- 题解
- 辗转相除法
- 当除数(分母)只有2或者5这两个质因数时,就是有限小数;当除数(分母)含有2和5以外的质因数时就是无限循环小数。
- coding
public class Main {
public static void main(String[] args) {
System.out.println(isLoop(1, 2));
}
public static boolean isLoop(long a, long b) {
long commonDivisor = greatestCommonDivisor(a, b);
b = b / commonDivisor;
while (b % 2 == 0){
b /= 2;
}
while (b % 5 == 0){
b /= 5;
}
if (b == 1){
return false;
}else {
return true;
}
}
public static long greatestCommonDivisor(long a, long b) {
long c = 0;
while (true) {
c = a % b;
a = b;
b = c;
if (b == 0) {
return a;
}
}
}
}
2、求两数相除的精确结果。如果有循环就只到循环节
class Solution{
public static Double getLoop(long a,long b){
StringBuilder result = new StringBuilder();
long commonDivisor = greatestCommonDivisor(a, b);
b = b / commonDivisor;
a = a / commonDivisor;
long[] ans = new long[1000];
long[] r = new long[1000];
int j , len = 0;
while (true){
ans[len] = (a / b);
a = a % b;
for (j = len; j > 0; j --) {
if (r[j] == a){
break;
}
}
if (a == 0 || j > 0){
break;
}else {
r[++len] = (int) a;
}
a *= 10;
}
result.append(ans[0]).append(".");
for (int i = 1; i <= len; i++) {
result.append(ans[i]);
}
return Double.parseDouble(result.toString());
}
}
3、超级次方-快速模幂运算
- 题解:
- 快速求幂公式。a8=(a4)2=(a4)∗(a4) 只需要对(a4)求幂
- 模运算规律。(a∗b)(modk)=(a(modk))∗(b(modk))(modk)
- coding
class Solution {
int base = 1337;
public int superPow(int a, int[] b) {
return superP(a, b, b.length - 1);
}
private int superP(int a, int[] b, int len) {
if (len == -1) return 1;
int last = b[len];
int part1 = myPow(a, last) % base;
int part2 = myPow(superP(a, b, len - 1), 10) % base;
return (part2 * part1) % base;
}
private int myPow(int a, int b) {
if (b == 0) return 1;
if (b % 2 == 1) {
return (a % base * myPow(a, b - 1) % base) % base;
} else {
int sub = myPow(a, b / 2) % base;
return (sub * sub) % base;
}
}
}
- 思路:
- 利用[1,n]的区间性质。每找到一个数 cur 让对应的下标位的数 arr[cur−1] 变为 负数
- 当 arr[cur−1]<0 时,代表 cur重复
- 遍历 arr[cur−1],当arr[cur−1]>0,表示该数缺失
- 时间复杂度:O(n) 空间复杂度:O(1)
- coding:
class Solution {
public int[] findErrorNums(int[] nums) {
int num1 = 0;
int num2 = 0;
for (int num : nums) {
int index = Math.abs(num) - 1;
if (nums[index] < 0){
num1 = Math.abs(num);
}else {
nums[index] *= -1;
}
}
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0){
num2 = i + 1;
break;
}
}
return new int[]{num1,num2};
}
}